Skip to contentSkip to conversation

Bluetooth: btqca: Introduce generic QCA ROME support

PATCH Superseded Ben Young Tae Kim 2 participants 2 messages Aug 7, 2015 – Aug 8, 2015

Subsystems (2)

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH v4 1/2 Bluetooth: btqca: Introduce generic QCA ROME support

This is for supporting BT for QCA ROME with specific vendor specific HCI commands and initialization. This will have USB/UART implementation both, but for now, adding UART vendor specific commands to patch downloading and set BDaddress using VS command.

---
 drivers/bluetooth/Kconfig  |   4 +
 drivers/bluetooth/Makefile |   1 +
 drivers/bluetooth/btqca.c  | 393 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/bluetooth/btqca.h  | 135 ++++++++++++++++
 4 files changed, 533 insertions(+)
 create mode 100644 drivers/bluetooth/btqca.c
 create mode 100644 drivers/bluetooth/btqca.h
drivers/bluetooth/Kconfig +4 -0
index 79e8234..f580334 100644
@@ -13,6 +13,10 @@ config BT_RTL
 	tristate
 	select FW_LOADER
 
+config BT_QCA
+	tristate
+	select FW_LOADER
+
 config BT_HCIBTUSB
 	tristate "HCI USB driver"
 	depends on USB
drivers/bluetooth/Makefile +1 -0
index f40e194..15a0d1d 100644
@@ -22,6 +22,7 @@ obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o
 obj-$(CONFIG_BT_WILINK)		+= btwilink.o
 obj-$(CONFIG_BT_BCM)		+= btbcm.o
 obj-$(CONFIG_BT_RTL)		+= btrtl.o
+obj-$(CONFIG_BT_QCA)		+= btqca.o
 
 btmrvl-y			:= btmrvl_main.o
 btmrvl-$(CONFIG_DEBUG_FS)	+= btmrvl_debugfs.o
drivers/bluetooth/btqca.c new file +393 -0

393 lines not on this page · raw message

drivers/bluetooth/btqca.h new file +135 -0

135 lines not on this page · raw message

Signature · 1 line
2.0.5
maintainer
#1 lore raw

Hi Ben,

Quoted 4 lines

This is for supporting BT for QCA ROME with specific vendor specific HCI commands and initialization. This will have USB/UART implementation both, but for now, adding UART vendor specific commands to patch downloading and set BDaddress using VS command.

lets write the BDaddress as Bluetooth device address. And replace VS with vendor specific. The commit message should be readable even by people that are not familiar with the Bluetooth terminology.

Quoted 69 lines

---

drivers/bluetooth/Kconfig  |   4 +
drivers/bluetooth/Makefile |   1 +
drivers/bluetooth/btqca.c  | 393 +++++++++++++++++++++++++++++++++++++++++++++
drivers/bluetooth/btqca.h  | 135 ++++++++++++++++
4 files changed, 533 insertions(+)

create mode 100644 drivers/bluetooth/btqca.c
create mode 100644 drivers/bluetooth/btqca.h

drivers/bluetooth/Kconfig +4 -0
index 79e8234..f580334 100644
@@ -13,6 +13,10 @@ config BT_RTL
 	tristate
 	select FW_LOADER
 
+config BT_QCA
+	tristate
+	select FW_LOADER
+

config BT_HCIBTUSB
tristate "HCI USB driver"
depends on USB

drivers/bluetooth/Makefile +0 -0
index f40e194..15a0d1d 100644
@@ -22,6 +22,7 @@ obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o

obj-$(CONFIG_BT_WILINK) += btwilink.o
obj-$(CONFIG_BT_BCM) += btbcm.o
obj-$(CONFIG_BT_RTL) += btrtl.o
+obj-$(CONFIG_BT_QCA) += btqca.o

btmrvl-y := btmrvl_main.o
btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o

drivers/bluetooth/btqca.c new file +26 -0
new file mode 100644
index 0000000..d119746
@@ -0,0 +1,393 @@
+/*
+ *  Bluetooth supports for Qualcomm Atheros chips
+ *
+ *  Copyright (c) 2015 The Linux Foundation. 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 version 2
+ *  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 the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/tty.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+

drivers/bluetooth/btqca.c line 36

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+#include "btqca.h"
+
+#define VERSION "0.1"
+
+static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version)
+{
+	struct sk_buff *skb;
+	struct edl_event_hdr *edl;
+	struct rome_version *ver;
+	char cmd;

Lets use u8 here instead of a signed char.

drivers/bluetooth/btqca.c line 37

Quoted 1 line
drivers/bluetooth/btqca.c new file +1 -0
+	int err, ret = 0;

Can we just use only err here. I don't think there is need to two variables.

Quoted 5 lines
drivers/bluetooth/btqca.c new file +5 -0
+
+	BT_DBG("%s: ROME Patch Version Request", hdev->name);
+
+	cmd = EDL_PATCH_VER_REQ_CMD;
+	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,

drivers/bluetooth/btqca.c line 52

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+				&cmd, HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: Failed to read version of ROME (%d)", hdev->name,
+		       err);
+		return err;
+	}
+
+	if (skb->len != sizeof(*edl) + sizeof(*ver)) {
+		BT_ERR("%s: version size mismatch len %d", hdev->name,

Lets write "Version" instead of "version".

drivers/bluetooth/btqca.c line 60

Quoted 8 lines
drivers/bluetooth/btqca.c new file +8 -0
+		       skb->len);
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	edl = (struct edl_event_hdr *)(skb->data);
+	if (!edl || !edl->data) {
+		BT_ERR("%s: tlv no hdr or no data", hdev->name);

Lets do "TLV with no header and no data" here.

drivers/bluetooth/btqca.c line 68

Quoted 8 lines
drivers/bluetooth/btqca.c new file +8 -0
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
+	    edl->rtype != EDL_APP_VER_RES_EVT) {
+		BT_ERR("%s: wrong packet received %d %d", hdev->name,
+		       edl->cresp, edl->rtype);

Lets do "Wrong" instead of "wrong" here.

drivers/bluetooth/btqca.c line 80

Quoted 12 lines
drivers/bluetooth/btqca.c new file +12 -0
+		ret = -EIO;
+		goto out;
+	}
+
+	ver = (struct rome_version *)(edl->data);
+
+	BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id));
+	BT_DBG("%s: Patch  :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver));
+	BT_DBG("%s: ROM    :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver));
+	BT_DBG("%s: SOC    :0x%08x", hdev->name, le32_to_cpu(ver->soc_id));
+
+	/* ROME chipset Version can be decided by patch and SOC

Lets make it "version" and write "SoC.

drivers/bluetooth/btqca.c line 81

Quoted 1 line
drivers/bluetooth/btqca.c new file +1 -0
+	 * Version, combination with upper 2 bytes from soc

Same here.

drivers/bluetooth/btqca.c line 82

Quoted 1 line
drivers/bluetooth/btqca.c new file +1 -0
+	 * and lower 2 bytes from patch will be used

If we have multi line comments and full sentences lets finish them with proper punctuation.

Quoted 11 lines
drivers/bluetooth/btqca.c new file +11 -0
+	 */
+	*rome_version = (le32_to_cpu(ver->soc_id) << 16) |
+		        (le16_to_cpu(ver->rome_ver) & 0x0000ffff);
+
+out:
+	kfree_skb(skb);
+
+	return ret;
+}
+
+static int rome_reset(struct hci_dev *hdev)

drivers/bluetooth/btqca.c line 103

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+{
+	struct sk_buff *skb;
+	int err;
+
+	BT_DBG("%s: ROME HCI_RESET", hdev->name);
+
+	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);

I think this is a Qualcomm chip and not a Broadcom one ;)

Since you have not used QCA prefix at all. Just call it "Reset failed".

Quoted 16 lines
drivers/bluetooth/btqca.c new file +16 -0
+		return err;
+	}
+
+	kfree_skb(skb);
+
+	return 0;
+}
+
+static void rome_tlv_check_data(struct rome_config *config,
+				const struct firmware *fw)
+{
+	const u8 *data;
+	u32 type_len;
+	u16 tag_id, tag_len;
+	int idx, length;
+	struct tlv_type_hdr *tlv;

drivers/bluetooth/btqca.c line 129

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+	struct tlv_type_patch *tlv_patch;
+	struct tlv_type_nvm *tlv_nvm;
+
+	tlv = (struct tlv_type_hdr *)fw->data;
+
+	type_len = le32_to_cpu(tlv->type_len);
+
+	BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
+	length = (type_len >> 8) & 0x00ffffff;
+	BT_DBG("Length\t\t : %d bytes", length);

This bugs me a little bit since the BT_DBG feels too noise. Lets just reorder this.

	tlv = (struct tlv_type_hdr *)fw->data;

	type_len = le32_to_cpu(tlv->type_len);
	length = (type_len >> 8) & 0x00ffffff;

	BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
	BT_DBG("Length\t\t : %d bytes", length);
Quoted 32 lines
drivers/bluetooth/btqca.c new file +32 -0
+
+	switch (config->type) {
+	case TLV_TYPE_PATCH:
+		tlv_patch = (struct tlv_type_patch *)tlv->data;
+		BT_DBG("Total Length\t\t : %d bytes",
+		       le32_to_cpu(tlv_patch->total_size));
+		BT_DBG("Patch Data Length\t : %d bytes",
+		       le32_to_cpu(tlv_patch->data_length));
+		BT_DBG("Signing Format Version : 0x%x",
+		       tlv_patch->format_version);
+		BT_DBG("Signature Algorithm\t : 0x%x",
+		       tlv_patch->signature);
+		BT_DBG("Reserved\t\t : 0x%x",
+		       le16_to_cpu(tlv_patch->reserved1));
+		BT_DBG("Product ID\t\t : 0x%04x",
+		       le16_to_cpu(tlv_patch->product_id));
+		BT_DBG("Rom Build Version\t : 0x%04x",
+		       le16_to_cpu(tlv_patch->rom_build));
+		BT_DBG("Patch Version\t\t : 0x%04x",
+		       le16_to_cpu(tlv_patch->patch_version));
+		BT_DBG("Reserved\t\t : 0x%x",
+		       le16_to_cpu(tlv_patch->reserved2));
+		BT_DBG("Patch Entry Address\t : 0x%x",
+		       le32_to_cpu(tlv_patch->entry));
+		break;
+
+	case TLV_TYPE_NVM:
+		idx = 0;
+		data = tlv->data;
+		while (idx < length) {
+			tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+

drivers/bluetooth/btqca.c line 171

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+			tag_id = le16_to_cpu(tlv_nvm->tag_id);
+			tag_len = le16_to_cpu(tlv_nvm->tag_len);
+
+			/* Update NVM tags as needed */
+			switch (tag_id) {
+			case EDL_TAG_ID_HCI:
+				/* HCI transport layer parameters
+				 * enabling software inband sleep
+				 * onto controller side
+				 */

Please end this sentence with a proper punctuation.

drivers/bluetooth/btqca.c line 181

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+				tlv_nvm->data[0] |= 0x80;
+
+				/* UART Baud Rate */
+				tlv_nvm->data[2] = config->user_baud_rate;
+
+				break;
+
+			case EDL_TAG_ID_DEEP_SLEEP:
+				/* Sleep enable mask
+				 * enabling deep sleep feature on controller

Same as above and might want to recheck the line break here.

drivers/bluetooth/btqca.c line 193

Quoted 12 lines
drivers/bluetooth/btqca.c new file +12 -0
+				 */
+				tlv_nvm->data[0] |= 0x01;
+
+				break;
+			}
+
+			idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
+		}
+		break;
+
+	default:
+		BT_ERR("unknown TLV type %d", config->type);

Use "Unknown" here.

Quoted 14 lines
drivers/bluetooth/btqca.c new file +14 -0
+		break;
+	}
+}
+
+static int rome_tlv_send_segment(struct hci_dev *hdev, int idx, int seg_size,
+				 const u8 *data)
+{
+	struct sk_buff *skb;
+	struct edl_event_hdr *edl;
+	struct tlv_seg_resp *tlv_resp;
+	u8 cmd[MAX_SIZE_PER_TLV_SEGMENT + 2];
+	int err, ret = 0;
+
+	BT_DBG("%s: Download segment #%d size %d", hdev->name, idx, seg_size);

drivers/bluetooth/btqca.c line 217

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+
+	cmd[0] = EDL_PATCH_TLV_REQ_CMD;
+	cmd[1] = seg_size;
+	memcpy(cmd + 2, data, seg_size);
+
+	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd,
+				HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: Failed to send TLV segment(%d)", hdev->name, err);

Extra space between segment and (%d).

drivers/bluetooth/btqca.c line 222

Quoted 5 lines
drivers/bluetooth/btqca.c new file +5 -0
+		return err;
+	}
+
+	if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) {
+		BT_ERR("%s: tlv response size mismatch", hdev->name);

Lets do "TLV" here.

drivers/bluetooth/btqca.c line 60

Quoted 7 lines
drivers/bluetooth/btqca.c new file +7 -0
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	edl = (struct edl_event_hdr *)(skb->data);
+	if (!edl || !edl->data) {
+		BT_ERR("%s: tlv no hdr or no data", hdev->name);

Change it to the same as mentioned earlier.

drivers/bluetooth/btqca.c line 239

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	tlv_resp = (struct tlv_seg_resp *)(edl->data);
+
+	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
+	    edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) {
+		BT_ERR("%s: tlv error stat 0x%x rtype 0x%x (0x%x)", hdev->name,
+		       edl->cresp, edl->rtype, tlv_resp->result);

See also above.

Quoted 47 lines
drivers/bluetooth/btqca.c new file +47 -0
+		ret = -EIO;
+	}
+
+out:
+	kfree_skb(skb);
+
+	return ret;
+}
+
+static int rome_tlv_download_request(struct hci_dev *hdev,
+				     const struct firmware *fw)
+{
+	const u8 *buffer, *data;
+	int total_segment, remain_size;
+	int ret, i;
+
+	if (!fw || !fw->data)
+		return -EINVAL;
+
+	total_segment = fw->size / MAX_SIZE_PER_TLV_SEGMENT;
+	remain_size = fw->size % MAX_SIZE_PER_TLV_SEGMENT;
+
+	BT_DBG("%s: total segment num %d remain size %d total size %zu",
+	       hdev->name, total_segment, remain_size, fw->size);
+
+	data = fw->data;
+	for (i = 0; i < total_segment; i++) {
+		buffer = data + i * MAX_SIZE_PER_TLV_SEGMENT;
+		ret = rome_tlv_send_segment(hdev, i, MAX_SIZE_PER_TLV_SEGMENT,
+					    buffer);
+		if (ret < 0)
+			return -EIO;
+	}
+
+	if (remain_size) {
+		buffer = data + total_segment * MAX_SIZE_PER_TLV_SEGMENT;
+		ret = rome_tlv_send_segment(hdev, total_segment, remain_size,
+					    buffer);
+		if (ret < 0)
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int rome_download_firmware(struct hci_dev *hdev,
+				  struct rome_config *config)

drivers/bluetooth/btqca.c line 296

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+{
+	const struct firmware *fw;
+	int ret;
+
+	BT_INFO("%s: ROME Downloading %s", hdev->name, config->fwname);
+
+	ret = request_firmware(&fw, config->fwname, &hdev->dev);
+	if (ret) {
+		BT_ERR("%s: failed to request file: %s (%d)", hdev->name,
+		       config->fwname, ret);

Use "Failed" here.

drivers/bluetooth/btqca.c line 305

Quoted 9 lines
drivers/bluetooth/btqca.c new file +9 -0
+		return ret;
+	}
+
+	rome_tlv_check_data(config, fw);
+
+	ret = rome_tlv_download_request(hdev, fw);
+	if (ret) {
+		BT_ERR("%s: fail to download file: %s (%d)", hdev->name,
+		       config->fwname, ret);

Use "Failed" here as well.

Quoted 29 lines
drivers/bluetooth/btqca.c new file +29 -0
+	}
+
+	release_firmware(fw);
+
+	return ret;
+}
+
+int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+	struct sk_buff *skb;
+	u8 cmd[9];
+	int err;
+
+	cmd[0] = EDL_NVM_ACCESS_SET_REQ_CMD;
+	cmd[1] = 0x02; 			/* TAG ID */
+	cmd[2] = sizeof(bdaddr_t);	/* size */
+	memcpy(cmd + 3, bdaddr, sizeof(bdaddr_t));
+	skb = __hci_cmd_sync_ev(hdev, EDL_NVM_ACCESS_OPCODE, sizeof(cmd), cmd,
+				HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		BT_ERR("%s: Change address command failed (%d)",
+		       hdev->name, err);
+		return err;
+	}
+
+	kfree_skb(skb);
+
+	return 0;

drivers/bluetooth/btqca.c line 344

Quoted 10 lines
drivers/bluetooth/btqca.c new file +10 -0
+}
+EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
+
+int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate)
+{
+	u32 rome_ver = 0;
+	struct rome_config config;
+	int err;
+
+	BT_DBG("%s: rome_uart_setup", hdev->name);

Replace rome_uart_setup with a descriptive name. The function name is already part of dynamic debug anyway.

drivers/bluetooth/btqca.c line 348

Quoted 4 lines
drivers/bluetooth/btqca.c new file +4 -0
+
+	config.user_baud_rate = baudrate;
+
+	/* get ROME version information */

Start with uppercase. So "Get" please.

drivers/bluetooth/btqca.c line 351

Quoted 3 lines
drivers/bluetooth/btqca.c new file +3 -0
+	err = rome_patch_ver_req(hdev, &rome_ver);
+	if (err < 0 || rome_ver == 0) {
+		BT_ERR("%s: Fail to get ROME version 0x%x",hdev->name, err);

Use "Failed" here.

And ,[:space:]hdev->name.

drivers/bluetooth/btqca.c line 357

Quoted 6 lines
drivers/bluetooth/btqca.c new file +6 -0
+		return err;
+	}
+
+	BT_INFO("%s: ROME controller version 0x%08x", hdev->name, rome_ver);
+
+	/* download rampatch file */

Use "Download" here.

drivers/bluetooth/btqca.c line 363

Quoted 6 lines
drivers/bluetooth/btqca.c new file +6 -0
+	config.type = TLV_TYPE_PATCH;
+	snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin",
+		 rome_ver);
+	err = rome_download_firmware(hdev, &config);
+	if (err < 0) {
+		BT_ERR("%s: can't download rampatch (%d)", hdev->name, err);

I would prefer "Failed to" instead of can't.

drivers/bluetooth/btqca.c line 367

Quoted 4 lines
drivers/bluetooth/btqca.c new file +4 -0
+		return err;
+	}
+
+	/* download NVM configuration */

Same as above.

drivers/bluetooth/btqca.c line 373

Quoted 6 lines
drivers/bluetooth/btqca.c new file +6 -0
+	config.type = TLV_TYPE_NVM;
+	snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin",
+		 rome_ver);
+	err = rome_download_firmware(hdev, &config);
+	if (err < 0) {
+		BT_ERR("%s: can't download NVM file (%d)", hdev->name, err);

Same as above.

drivers/bluetooth/btqca.c line 377

Quoted 4 lines
drivers/bluetooth/btqca.c new file +4 -0
+		return err;
+	}
+
+	/* perform HCI reset */

Use "Perform" here.

drivers/bluetooth/btqca.c line 380

Quoted 3 lines
drivers/bluetooth/btqca.c new file +3 -0
+	err = rome_reset(hdev);
+	if (err < 0) {
+		BT_ERR("%s: can't run HCI_RESET (%d)", hdev->name, err);

See above.

drivers/bluetooth/btqca.c line 384

Quoted 4 lines
drivers/bluetooth/btqca.c new file +4 -0
+		return err;
+	}
+
+	BT_INFO("%s: ROME uart setup is completed", hdev->name);

Generally I think it is written "UART".

Quoted 140 lines
drivers/bluetooth/btqca.c new file +9 -0
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(qca_uart_setup_rome);
+
+MODULE_AUTHOR("Ben Young Tae Kim <[email protected]>");
+MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
drivers/bluetooth/btqca.h new file +125 -0
new file mode 100644
index 0000000..65e994b
@@ -0,0 +1,135 @@
+/*
+ *  Bluetooth supports for Qualcomm Atheros ROME chips
+ *
+ *  Copyright (c) 2015 The Linux Foundation. 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 version 2
+ *  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 the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define EDL_PATCH_CMD_OPCODE		(0xFC00)
+#define EDL_NVM_ACCESS_OPCODE		(0xFC0B)
+#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)
+
+enum qca_bardrate {
+	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_type {
+	TLV_TYPE_PATCH = 1,
+	TLV_TYPE_NVM
+};
+
+struct rome_config {
+	u8 type;
+	char fwname[64];
+	uint8_t user_baud_rate;
+};
+
+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;
+	__le16 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;
+
+#if IS_ENABLED(CONFIG_BT_QCA)
+
+int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate);
+
+#else
+
+static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)

drivers/bluetooth/btqca.h line 135

Quoted 10 lines
drivers/bluetooth/btqca.h new file +10 -0
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int qca_uart_setup_rome(struct hci_dev *hdev, int speed)
+{
+	return -EOPNOTSUPP;
+}
+
+#endif

So we only have cosmetic changes left. Please address these and then we should be ready to merge this for further exposure.

Regards

Marcel