summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btbcm.c
diff options
context:
space:
mode:
authorFrederic Danis <frederic.danis@linux.intel.com>2015-05-28 05:25:04 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-06-06 01:33:25 -0400
commit75e167e6f0ddcf65567c0a604e4827f0a914a4c1 (patch)
treeebae5dfc21095ce5a39d1ed63236e340ed7db63f /drivers/bluetooth/btbcm.c
parent7721383f4199bb704c664f009423bc228bbac52e (diff)
Bluetooth: btbcm: Add helper functions for UART setup
Firmware loading may reset the controller UART speed and needs to set host UART speed back to init speed. UART drivers setup is split in 3 parts: - btbcm_initialize() resets the controller and returns the firmware name based on controller revision and sub_version. - btbtcm_patchram() (already existing and public), which takes the firmware name as parameter, requests the firmware and loads it to the controller. - btbcm_finalize() which resets the controller, reads local version and checks if the controller address is a default one or not. Remove firmware name retrieval for UART controllers from btbcm_setup_patchram(). Signed-off-by: Frederic Danis <frederic.danis@linux.intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth/btbcm.c')
-rw-r--r--drivers/bluetooth/btbcm.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index 14e4647686bd..8e2f6b6251c4 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -246,6 +246,95 @@ static const struct {
246 { } 246 { }
247}; 247};
248 248
249int 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}
302EXPORT_SYMBOL_GPL(btbcm_initialize);
303
304int 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}
336EXPORT_SYMBOL_GPL(btbcm_finalize);
337
249static const struct { 338static const struct {
250 u16 subver; 339 u16 subver;
251 const char *name; 340 const char *name;