xref: /openbmc/linux/drivers/bluetooth/btbcm.c (revision 4f3db074)
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 #include <linux/firmware.h>
26 #include <asm/unaligned.h>
27 
28 #include <net/bluetooth/bluetooth.h>
29 #include <net/bluetooth/hci_core.h>
30 
31 #include "btbcm.h"
32 
33 #define VERSION "0.1"
34 
35 #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
36 
37 int btbcm_check_bdaddr(struct hci_dev *hdev)
38 {
39 	struct hci_rp_read_bd_addr *bda;
40 	struct sk_buff *skb;
41 
42 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
43 			     HCI_INIT_TIMEOUT);
44 	if (IS_ERR(skb)) {
45 		int err = PTR_ERR(skb);
46 		BT_ERR("%s: BCM: Reading device address failed (%d)",
47 		       hdev->name, err);
48 		return err;
49 	}
50 
51 	if (skb->len != sizeof(*bda)) {
52 		BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
53 		kfree_skb(skb);
54 		return -EIO;
55 	}
56 
57 	bda = (struct hci_rp_read_bd_addr *)skb->data;
58 	if (bda->status) {
59 		BT_ERR("%s: BCM: Device address result failed (%02x)",
60 		       hdev->name, bda->status);
61 		kfree_skb(skb);
62 		return -bt_to_errno(bda->status);
63 	}
64 
65 	/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
66 	 * with no configured address.
67 	 */
68 	if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
69 		BT_INFO("%s: BCM: Using default device address (%pMR)",
70 			hdev->name, &bda->bdaddr);
71 		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
72 	}
73 
74 	kfree_skb(skb);
75 
76 	return 0;
77 }
78 EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
79 
80 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
81 {
82 	struct sk_buff *skb;
83 	int err;
84 
85 	skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
86 	if (IS_ERR(skb)) {
87 		err = PTR_ERR(skb);
88 		BT_ERR("%s: BCM: Change address command failed (%d)",
89 		       hdev->name, err);
90 		return err;
91 	}
92 	kfree_skb(skb);
93 
94 	return 0;
95 }
96 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
97 
98 static int btbcm_reset(struct hci_dev *hdev)
99 {
100 	struct sk_buff *skb;
101 
102 	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
103 	if (IS_ERR(skb)) {
104 		int err = PTR_ERR(skb);
105 		BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);
106 		return err;
107 	}
108 	kfree_skb(skb);
109 
110 	return 0;
111 }
112 
113 static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
114 {
115 	struct sk_buff *skb;
116 
117 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
118 			     HCI_INIT_TIMEOUT);
119 	if (IS_ERR(skb)) {
120 		BT_ERR("%s: BCM: Reading local version info failed (%ld)",
121 		       hdev->name, PTR_ERR(skb));
122 		return skb;
123 	}
124 
125 	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
126 		BT_ERR("%s: BCM: Local version length mismatch", hdev->name);
127 		kfree_skb(skb);
128 		return ERR_PTR(-EIO);
129 	}
130 
131 	return skb;
132 }
133 
134 static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
135 {
136 	struct sk_buff *skb;
137 
138 	skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
139 	if (IS_ERR(skb)) {
140 		BT_ERR("%s: BCM: Read verbose config info failed (%ld)",
141 		       hdev->name, PTR_ERR(skb));
142 		return skb;
143 	}
144 
145 	if (skb->len != 7) {
146 		BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name);
147 		kfree_skb(skb);
148 		return ERR_PTR(-EIO);
149 	}
150 
151 	return skb;
152 }
153 
154 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
155 {
156 	struct sk_buff *skb;
157 
158 	skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
159 	if (IS_ERR(skb)) {
160 		BT_ERR("%s: BCM: Read USB product info failed (%ld)",
161 		       hdev->name, PTR_ERR(skb));
162 		return skb;
163 	}
164 
165 	if (skb->len != 5) {
166 		BT_ERR("%s: BCM: USB product length mismatch", hdev->name);
167 		kfree_skb(skb);
168 		return ERR_PTR(-EIO);
169 	}
170 
171 	return skb;
172 }
173 
174 static const struct {
175 	u16 subver;
176 	const char *name;
177 } bcm_uart_subver_table[] = {
178 	{ 0x410e, "BCM43341B0"	},	/* 002.001.014 */
179 	{ }
180 };
181 
182 static const struct {
183 	u16 subver;
184 	const char *name;
185 } bcm_usb_subver_table[] = {
186 	{ 0x210b, "BCM43142A0"	},	/* 001.001.011 */
187 	{ 0x2112, "BCM4314A0"	},	/* 001.001.018 */
188 	{ 0x2118, "BCM20702A0"	},	/* 001.001.024 */
189 	{ 0x2126, "BCM4335A0"	},	/* 001.001.038 */
190 	{ 0x220e, "BCM20702A1"	},	/* 001.002.014 */
191 	{ 0x230f, "BCM4354A2"	},	/* 001.003.015 */
192 	{ 0x4106, "BCM4335B0"	},	/* 002.001.006 */
193 	{ 0x410e, "BCM20702B0"	},	/* 002.001.014 */
194 	{ 0x6109, "BCM4335C0"	},	/* 003.001.009 */
195 	{ 0x610c, "BCM4354"	},	/* 003.001.012 */
196 	{ }
197 };
198 
199 int btbcm_setup_patchram(struct hci_dev *hdev)
200 {
201 	const struct hci_command_hdr *cmd;
202 	const struct firmware *fw;
203 	const u8 *fw_ptr;
204 	size_t fw_size;
205 	char fw_name[64];
206 	u16 opcode, subver, rev, pid, vid;
207 	const char *hw_name = NULL;
208 	struct sk_buff *skb;
209 	struct hci_rp_read_local_version *ver;
210 	int i, err;
211 
212 	/* Reset */
213 	err = btbcm_reset(hdev);
214 	if (err)
215 		return err;
216 
217 	/* Read Local Version Info */
218 	skb = btbcm_read_local_version(hdev);
219 	if (IS_ERR(skb))
220 		return PTR_ERR(skb);
221 
222 	ver = (struct hci_rp_read_local_version *)skb->data;
223 	rev = le16_to_cpu(ver->hci_rev);
224 	subver = le16_to_cpu(ver->lmp_subver);
225 	kfree_skb(skb);
226 
227 	/* Read Verbose Config Version Info */
228 	skb = btbcm_read_verbose_config(hdev);
229 	if (IS_ERR(skb))
230 		return PTR_ERR(skb);
231 
232 	BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
233 	kfree_skb(skb);
234 
235 	switch ((rev & 0xf000) >> 12) {
236 	case 0:
237 		for (i = 0; bcm_uart_subver_table[i].name; i++) {
238 			if (subver == bcm_uart_subver_table[i].subver) {
239 				hw_name = bcm_uart_subver_table[i].name;
240 				break;
241 			}
242 		}
243 
244 		snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
245 			 hw_name ? : "BCM");
246 		break;
247 	case 1:
248 	case 2:
249 		/* Read USB Product Info */
250 		skb = btbcm_read_usb_product(hdev);
251 		if (IS_ERR(skb))
252 			return PTR_ERR(skb);
253 
254 		vid = get_unaligned_le16(skb->data + 1);
255 		pid = get_unaligned_le16(skb->data + 3);
256 		kfree_skb(skb);
257 
258 		for (i = 0; bcm_usb_subver_table[i].name; i++) {
259 			if (subver == bcm_usb_subver_table[i].subver) {
260 				hw_name = bcm_usb_subver_table[i].name;
261 				break;
262 			}
263 		}
264 
265 		snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
266 			 hw_name ? : "BCM", vid, pid);
267 		break;
268 	default:
269 		return 0;
270 	}
271 
272 	BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
273 		hw_name ? : "BCM", (subver & 0x7000) >> 13,
274 		(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
275 
276 	err = request_firmware(&fw, fw_name, &hdev->dev);
277 	if (err < 0) {
278 		BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
279 		return 0;
280 	}
281 
282 	/* Start Download */
283 	skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
284 	if (IS_ERR(skb)) {
285 		err = PTR_ERR(skb);
286 		BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
287 		       hdev->name, err);
288 		goto reset;
289 	}
290 	kfree_skb(skb);
291 
292 	/* 50 msec delay after Download Minidrv completes */
293 	msleep(50);
294 
295 	fw_ptr = fw->data;
296 	fw_size = fw->size;
297 
298 	while (fw_size >= sizeof(*cmd)) {
299 		const u8 *cmd_param;
300 
301 		cmd = (struct hci_command_hdr *)fw_ptr;
302 		fw_ptr += sizeof(*cmd);
303 		fw_size -= sizeof(*cmd);
304 
305 		if (fw_size < cmd->plen) {
306 			BT_ERR("%s: BCM: patch %s is corrupted", hdev->name,
307 			       fw_name);
308 			err = -EINVAL;
309 			goto reset;
310 		}
311 
312 		cmd_param = fw_ptr;
313 		fw_ptr += cmd->plen;
314 		fw_size -= cmd->plen;
315 
316 		opcode = le16_to_cpu(cmd->opcode);
317 
318 		skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
319 				     HCI_INIT_TIMEOUT);
320 		if (IS_ERR(skb)) {
321 			err = PTR_ERR(skb);
322 			BT_ERR("%s: BCM: patch command %04x failed (%d)",
323 			       hdev->name, opcode, err);
324 			goto reset;
325 		}
326 		kfree_skb(skb);
327 	}
328 
329 	/* 250 msec delay after Launch Ram completes */
330 	msleep(250);
331 
332 reset:
333 	/* Reset */
334 	err = btbcm_reset(hdev);
335 	if (err)
336 		goto done;
337 
338 	/* Read Local Version Info */
339 	skb = btbcm_read_local_version(hdev);
340 	if (IS_ERR(skb)) {
341 		err = PTR_ERR(skb);
342 		goto done;
343 	}
344 
345 	ver = (struct hci_rp_read_local_version *)skb->data;
346 	rev = le16_to_cpu(ver->hci_rev);
347 	subver = le16_to_cpu(ver->lmp_subver);
348 	kfree_skb(skb);
349 
350 	BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
351 		hw_name ? : "BCM", (subver & 0x7000) >> 13,
352 		(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
353 
354 	btbcm_check_bdaddr(hdev);
355 
356 	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
357 
358 done:
359 	release_firmware(fw);
360 
361 	return err;
362 }
363 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
364 
365 int btbcm_setup_apple(struct hci_dev *hdev)
366 {
367 	struct sk_buff *skb;
368 
369 	/* Read Verbose Config Version Info */
370 	skb = btbcm_read_verbose_config(hdev);
371 	if (IS_ERR(skb))
372 		return PTR_ERR(skb);
373 
374 	BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1],
375 		get_unaligned_le16(skb->data + 5));
376 	kfree_skb(skb);
377 
378 	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
379 
380 	return 0;
381 }
382 EXPORT_SYMBOL_GPL(btbcm_setup_apple);
383 
384 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
385 MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
386 MODULE_VERSION(VERSION);
387 MODULE_LICENSE("GPL");
388