aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-04-06 01:52:10 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-04-07 12:47:11 -0400
commit4fba30f07f51617438835f75b58e37fb610b2d8d (patch)
tree10e786a1a8c3d3d0a19d9f6016d0a1e99657170a
parent788a675675b3ec5b64d232eae25e8e3e897cd31b (diff)
Bluetooth: btbcm: Introduce generic Broadcom Bluetooth support
The majority of Broadcom Bluetooth vendor commands are shared between USB and UART transports. This creates a separate module that eventually will hold all Broadcom specific commands, but for now just start with the commands to change the Bluetooth public address and check for the default address. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r--drivers/bluetooth/Kconfig3
-rw-r--r--drivers/bluetooth/Makefile1
-rw-r--r--drivers/bluetooth/btbcm.c99
-rw-r--r--drivers/bluetooth/btbcm.h41
4 files changed, 144 insertions, 0 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index f8a41975c30d..4fbe067cd33a 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -2,6 +2,9 @@
2menu "Bluetooth device drivers" 2menu "Bluetooth device drivers"
3 depends on BT 3 depends on BT
4 4
5config BT_BCM
6 tristate
7
5config BT_HCIBTUSB 8config BT_HCIBTUSB
6 tristate "HCI USB driver" 9 tristate "HCI USB driver"
7 depends on USB 10 depends on USB
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 51f9d0c18963..51c98546fa03 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_BT_ATH3K) += ath3k.o
19obj-$(CONFIG_BT_MRVL) += btmrvl.o 19obj-$(CONFIG_BT_MRVL) += btmrvl.o
20obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o 20obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o
21obj-$(CONFIG_BT_WILINK) += btwilink.o 21obj-$(CONFIG_BT_WILINK) += btwilink.o
22obj-$(CONFIG_BT_BCM) += btbcm.o
22 23
23btmrvl-y := btmrvl_main.o 24btmrvl-y := btmrvl_main.o
24btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o 25btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
new file mode 100644
index 000000000000..20c744a9a3f1
--- /dev/null
+++ b/drivers/bluetooth/btbcm.c
@@ -0,0 +1,99 @@
1/*
2 *
3 * Bluetooth support for Broadcom devices
4 *
5 * Copyright (C) 2015 Intel Corporation
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/module.h>
25
26#include <net/bluetooth/bluetooth.h>
27#include <net/bluetooth/hci_core.h>
28
29#include "btbcm.h"
30
31#define VERSION "0.1"
32
33#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
34
35int btbcm_check_bdaddr(struct hci_dev *hdev)
36{
37 struct hci_rp_read_bd_addr *bda;
38 struct sk_buff *skb;
39
40 skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
41 HCI_INIT_TIMEOUT);
42 if (IS_ERR(skb)) {
43 int err = PTR_ERR(skb);
44 BT_ERR("%s: BCM: Reading device address failed (%d)",
45 hdev->name, err);
46 return err;
47 }
48
49 if (skb->len != sizeof(*bda)) {
50 BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
51 kfree_skb(skb);
52 return -EIO;
53 }
54
55 bda = (struct hci_rp_read_bd_addr *)skb->data;
56 if (bda->status) {
57 BT_ERR("%s: BCM: Device address result failed (%02x)",
58 hdev->name, bda->status);
59 kfree_skb(skb);
60 return -bt_to_errno(bda->status);
61 }
62
63 /* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
64 * with no configured address.
65 */
66 if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
67 BT_INFO("%s: BCM: Using default device address (%pMR)",
68 hdev->name, &bda->bdaddr);
69 set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
70 }
71
72 kfree_skb(skb);
73
74 return 0;
75}
76EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
77
78int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
79{
80 struct sk_buff *skb;
81 int err;
82
83 skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
84 if (IS_ERR(skb)) {
85 err = PTR_ERR(skb);
86 BT_ERR("%s: BCM: Change address command failed (%d)",
87 hdev->name, err);
88 return err;
89 }
90 kfree_skb(skb);
91
92 return 0;
93}
94EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
95
96MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
97MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
98MODULE_VERSION(VERSION);
99MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h
new file mode 100644
index 000000000000..813f7e7e191d
--- /dev/null
+++ b/drivers/bluetooth/btbcm.h
@@ -0,0 +1,41 @@
1/*
2 *
3 * Bluetooth support for Broadcom devices
4 *
5 * Copyright (C) 2015 Intel Corporation
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#if IS_ENABLED(CONFIG_BT_BCM)
25
26int btbcm_check_bdaddr(struct hci_dev *hdev);
27int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
28
29#else
30
31static inline int btbcm_check_bdaddr(struct hci_dev *hdev)
32{
33 return -EOPNOTSUPP;
34}
35
36static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
37{
38 return -EOPNOTSUPP;
39}
40
41#endif