Bluetooth: btbcm: Add helper functions for UART setup
[firefly-linux-kernel-4.4.55.git] / drivers / bluetooth / btbcm.c
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 #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}})
37
38 int btbcm_check_bdaddr(struct hci_dev *hdev)
39 {
40         struct hci_rp_read_bd_addr *bda;
41         struct sk_buff *skb;
42
43         skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
44                              HCI_INIT_TIMEOUT);
45         if (IS_ERR(skb)) {
46                 int err = PTR_ERR(skb);
47                 BT_ERR("%s: BCM: Reading device address failed (%d)",
48                        hdev->name, err);
49                 return err;
50         }
51
52         if (skb->len != sizeof(*bda)) {
53                 BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
54                 kfree_skb(skb);
55                 return -EIO;
56         }
57
58         bda = (struct hci_rp_read_bd_addr *)skb->data;
59
60         /* Check if the address indicates a controller with either an
61          * invalid or default address. In both cases the device needs
62          * to be marked as not having a valid address.
63          *
64          * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
65          * with no configured address.
66          *
67          * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller
68          * with waiting for configuration state.
69          */
70         if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) ||
71             !bacmp(&bda->bdaddr, BDADDR_BCM4324B3)) {
72                 BT_INFO("%s: BCM: Using default device address (%pMR)",
73                         hdev->name, &bda->bdaddr);
74                 set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
75         }
76
77         kfree_skb(skb);
78
79         return 0;
80 }
81 EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
82
83 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
84 {
85         struct sk_buff *skb;
86         int err;
87
88         skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
89         if (IS_ERR(skb)) {
90                 err = PTR_ERR(skb);
91                 BT_ERR("%s: BCM: Change address command failed (%d)",
92                        hdev->name, err);
93                 return err;
94         }
95         kfree_skb(skb);
96
97         return 0;
98 }
99 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
100
101 int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
102 {
103         const struct hci_command_hdr *cmd;
104         const u8 *fw_ptr;
105         size_t fw_size;
106         struct sk_buff *skb;
107         u16 opcode;
108         int err = 0;
109
110         /* Start Download */
111         skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
112         if (IS_ERR(skb)) {
113                 err = PTR_ERR(skb);
114                 BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
115                        hdev->name, err);
116                 goto done;
117         }
118         kfree_skb(skb);
119
120         /* 50 msec delay after Download Minidrv completes */
121         msleep(50);
122
123         fw_ptr = fw->data;
124         fw_size = fw->size;
125
126         while (fw_size >= sizeof(*cmd)) {
127                 const u8 *cmd_param;
128
129                 cmd = (struct hci_command_hdr *)fw_ptr;
130                 fw_ptr += sizeof(*cmd);
131                 fw_size -= sizeof(*cmd);
132
133                 if (fw_size < cmd->plen) {
134                         BT_ERR("%s: BCM: Patch is corrupted", hdev->name);
135                         err = -EINVAL;
136                         goto done;
137                 }
138
139                 cmd_param = fw_ptr;
140                 fw_ptr += cmd->plen;
141                 fw_size -= cmd->plen;
142
143                 opcode = le16_to_cpu(cmd->opcode);
144
145                 skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
146                                      HCI_INIT_TIMEOUT);
147                 if (IS_ERR(skb)) {
148                         err = PTR_ERR(skb);
149                         BT_ERR("%s: BCM: Patch command %04x failed (%d)",
150                                hdev->name, opcode, err);
151                         goto done;
152                 }
153                 kfree_skb(skb);
154         }
155
156         /* 250 msec delay after Launch Ram completes */
157         msleep(250);
158
159 done:
160         return err;
161 }
162 EXPORT_SYMBOL(btbcm_patchram);
163
164 static int btbcm_reset(struct hci_dev *hdev)
165 {
166         struct sk_buff *skb;
167
168         skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
169         if (IS_ERR(skb)) {
170                 int err = PTR_ERR(skb);
171                 BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);
172                 return err;
173         }
174         kfree_skb(skb);
175
176         return 0;
177 }
178
179 static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
180 {
181         struct sk_buff *skb;
182
183         skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
184                              HCI_INIT_TIMEOUT);
185         if (IS_ERR(skb)) {
186                 BT_ERR("%s: BCM: Reading local version info failed (%ld)",
187                        hdev->name, PTR_ERR(skb));
188                 return skb;
189         }
190
191         if (skb->len != sizeof(struct hci_rp_read_local_version)) {
192                 BT_ERR("%s: BCM: Local version length mismatch", hdev->name);
193                 kfree_skb(skb);
194                 return ERR_PTR(-EIO);
195         }
196
197         return skb;
198 }
199
200 static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
201 {
202         struct sk_buff *skb;
203
204         skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
205         if (IS_ERR(skb)) {
206                 BT_ERR("%s: BCM: Read verbose config info failed (%ld)",
207                        hdev->name, PTR_ERR(skb));
208                 return skb;
209         }
210
211         if (skb->len != 7) {
212                 BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name);
213                 kfree_skb(skb);
214                 return ERR_PTR(-EIO);
215         }
216
217         return skb;
218 }
219
220 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
221 {
222         struct sk_buff *skb;
223
224         skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
225         if (IS_ERR(skb)) {
226                 BT_ERR("%s: BCM: Read USB product info failed (%ld)",
227                        hdev->name, PTR_ERR(skb));
228                 return skb;
229         }
230
231         if (skb->len != 5) {
232                 BT_ERR("%s: BCM: USB product length mismatch", hdev->name);
233                 kfree_skb(skb);
234                 return ERR_PTR(-EIO);
235         }
236
237         return skb;
238 }
239
240 static const struct {
241         u16 subver;
242         const char *name;
243 } bcm_uart_subver_table[] = {
244         { 0x410e, "BCM43341B0"  },      /* 002.001.014 */
245         { 0x4406, "BCM4324B3"   },      /* 002.004.006 */
246         { }
247 };
248
249 int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len)
250 {
251         u16 subver, rev;
252         const char *hw_name = NULL;
253         struct sk_buff *skb;
254         struct hci_rp_read_local_version *ver;
255         int i, err;
256
257         /* Reset */
258         err = btbcm_reset(hdev);
259         if (err)
260                 return err;
261
262         /* Read Local Version Info */
263         skb = btbcm_read_local_version(hdev);
264         if (IS_ERR(skb))
265                 return PTR_ERR(skb);
266
267         ver = (struct hci_rp_read_local_version *)skb->data;
268         rev = le16_to_cpu(ver->hci_rev);
269         subver = le16_to_cpu(ver->lmp_subver);
270         kfree_skb(skb);
271
272         /* Read Verbose Config Version Info */
273         skb = btbcm_read_verbose_config(hdev);
274         if (IS_ERR(skb))
275                 return PTR_ERR(skb);
276
277         BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
278         kfree_skb(skb);
279
280         switch ((rev & 0xf000) >> 12) {
281         case 0:
282         case 3:
283                 for (i = 0; bcm_uart_subver_table[i].name; i++) {
284                         if (subver == bcm_uart_subver_table[i].subver) {
285                                 hw_name = bcm_uart_subver_table[i].name;
286                                 break;
287                         }
288                 }
289
290                 snprintf(fw_name, len, "brcm/%s.hcd", hw_name ? : "BCM");
291                 break;
292         default:
293                 return 0;
294         }
295
296         BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
297                 hw_name ? : "BCM", (subver & 0x7000) >> 13,
298                 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
299
300         return 0;
301 }
302 EXPORT_SYMBOL_GPL(btbcm_initialize);
303
304 int btbcm_finalize(struct hci_dev *hdev)
305 {
306         struct sk_buff *skb;
307         struct hci_rp_read_local_version *ver;
308         u16 subver, rev;
309         int err;
310
311         /* Reset */
312         err = btbcm_reset(hdev);
313         if (err)
314                 return err;
315
316         /* Read Local Version Info */
317         skb = btbcm_read_local_version(hdev);
318         if (IS_ERR(skb))
319                 return PTR_ERR(skb);
320
321         ver = (struct hci_rp_read_local_version *)skb->data;
322         rev = le16_to_cpu(ver->hci_rev);
323         subver = le16_to_cpu(ver->lmp_subver);
324         kfree_skb(skb);
325
326         BT_INFO("%s: BCM (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
327                 (subver & 0x7000) >> 13, (subver & 0x1f00) >> 8,
328                 (subver & 0x00ff), rev & 0x0fff);
329
330         btbcm_check_bdaddr(hdev);
331
332         set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
333
334         return 0;
335 }
336 EXPORT_SYMBOL_GPL(btbcm_finalize);
337
338 static const struct {
339         u16 subver;
340         const char *name;
341 } bcm_usb_subver_table[] = {
342         { 0x210b, "BCM43142A0"  },      /* 001.001.011 */
343         { 0x2112, "BCM4314A0"   },      /* 001.001.018 */
344         { 0x2118, "BCM20702A0"  },      /* 001.001.024 */
345         { 0x2126, "BCM4335A0"   },      /* 001.001.038 */
346         { 0x220e, "BCM20702A1"  },      /* 001.002.014 */
347         { 0x230f, "BCM4354A2"   },      /* 001.003.015 */
348         { 0x4106, "BCM4335B0"   },      /* 002.001.006 */
349         { 0x410e, "BCM20702B0"  },      /* 002.001.014 */
350         { 0x6109, "BCM4335C0"   },      /* 003.001.009 */
351         { 0x610c, "BCM4354"     },      /* 003.001.012 */
352         { }
353 };
354
355 int btbcm_setup_patchram(struct hci_dev *hdev)
356 {
357         char fw_name[64];
358         const struct firmware *fw;
359         u16 subver, rev, pid, vid;
360         const char *hw_name = NULL;
361         struct sk_buff *skb;
362         struct hci_rp_read_local_version *ver;
363         int i, err;
364
365         /* Reset */
366         err = btbcm_reset(hdev);
367         if (err)
368                 return err;
369
370         /* Read Local Version Info */
371         skb = btbcm_read_local_version(hdev);
372         if (IS_ERR(skb))
373                 return PTR_ERR(skb);
374
375         ver = (struct hci_rp_read_local_version *)skb->data;
376         rev = le16_to_cpu(ver->hci_rev);
377         subver = le16_to_cpu(ver->lmp_subver);
378         kfree_skb(skb);
379
380         /* Read Verbose Config Version Info */
381         skb = btbcm_read_verbose_config(hdev);
382         if (IS_ERR(skb))
383                 return PTR_ERR(skb);
384
385         BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
386         kfree_skb(skb);
387
388         switch ((rev & 0xf000) >> 12) {
389         case 0:
390         case 3:
391                 for (i = 0; bcm_uart_subver_table[i].name; i++) {
392                         if (subver == bcm_uart_subver_table[i].subver) {
393                                 hw_name = bcm_uart_subver_table[i].name;
394                                 break;
395                         }
396                 }
397
398                 snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
399                          hw_name ? : "BCM");
400                 break;
401         case 1:
402         case 2:
403                 /* Read USB Product Info */
404                 skb = btbcm_read_usb_product(hdev);
405                 if (IS_ERR(skb))
406                         return PTR_ERR(skb);
407
408                 vid = get_unaligned_le16(skb->data + 1);
409                 pid = get_unaligned_le16(skb->data + 3);
410                 kfree_skb(skb);
411
412                 for (i = 0; bcm_usb_subver_table[i].name; i++) {
413                         if (subver == bcm_usb_subver_table[i].subver) {
414                                 hw_name = bcm_usb_subver_table[i].name;
415                                 break;
416                         }
417                 }
418
419                 snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
420                          hw_name ? : "BCM", vid, pid);
421                 break;
422         default:
423                 return 0;
424         }
425
426         BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
427                 hw_name ? : "BCM", (subver & 0x7000) >> 13,
428                 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
429
430         err = request_firmware(&fw, fw_name, &hdev->dev);
431         if (err < 0) {
432                 BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name);
433                 return 0;
434         }
435
436         btbcm_patchram(hdev, fw);
437
438         release_firmware(fw);
439
440         /* Reset */
441         err = btbcm_reset(hdev);
442         if (err)
443                 return err;
444
445         /* Read Local Version Info */
446         skb = btbcm_read_local_version(hdev);
447         if (IS_ERR(skb))
448                 return PTR_ERR(skb);
449
450         ver = (struct hci_rp_read_local_version *)skb->data;
451         rev = le16_to_cpu(ver->hci_rev);
452         subver = le16_to_cpu(ver->lmp_subver);
453         kfree_skb(skb);
454
455         BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
456                 hw_name ? : "BCM", (subver & 0x7000) >> 13,
457                 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
458
459         btbcm_check_bdaddr(hdev);
460
461         set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
462
463         return 0;
464 }
465 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
466
467 int btbcm_setup_apple(struct hci_dev *hdev)
468 {
469         struct sk_buff *skb;
470
471         /* Read Verbose Config Version Info */
472         skb = btbcm_read_verbose_config(hdev);
473         if (IS_ERR(skb))
474                 return PTR_ERR(skb);
475
476         BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1],
477                 get_unaligned_le16(skb->data + 5));
478         kfree_skb(skb);
479
480         set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
481
482         return 0;
483 }
484 EXPORT_SYMBOL_GPL(btbcm_setup_apple);
485
486 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
487 MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
488 MODULE_VERSION(VERSION);
489 MODULE_LICENSE("GPL");