diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 90 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.h | 1 |
2 files changed, 38 insertions, 53 deletions
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 8f13e7bea0ba..867ebe4b8e96 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -31,10 +31,6 @@ | |||
31 | 31 | ||
32 | #define VERSION "1.0" | 32 | #define VERSION "1.0" |
33 | 33 | ||
34 | #ifndef SDIO_DEVICE_ID_MARVELL_8688BT | ||
35 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 | ||
36 | #endif | ||
37 | |||
38 | /* The btmrvl_sdio_remove() callback function is called | 34 | /* The btmrvl_sdio_remove() callback function is called |
39 | * when user removes this module from kernel space or ejects | 35 | * when user removes this module from kernel space or ejects |
40 | * the card from the slot. The driver handles these 2 cases | 36 | * the card from the slot. The driver handles these 2 cases |
@@ -51,21 +47,21 @@ | |||
51 | */ | 47 | */ |
52 | static u8 user_rmmod; | 48 | static u8 user_rmmod; |
53 | 49 | ||
54 | static const struct sdio_device_id btmrvl_sdio_ids[] = { | 50 | static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { |
55 | {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8688BT)}, | 51 | .helper = "sd8688_helper.bin", |
56 | {0, 0, 0, 0} | 52 | .firmware = "sd8688.bin", |
57 | }; | 53 | }; |
58 | 54 | ||
59 | MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids); | 55 | static const struct sdio_device_id btmrvl_sdio_ids[] = { |
56 | /* Marvell SD8688 Bluetooth device */ | ||
57 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), | ||
58 | .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, | ||
60 | 59 | ||
61 | static struct btmrvl_sdio_device btmrvl_sdio_devices[] = { | 60 | { } /* Terminating entry */ |
62 | { | ||
63 | .dev_id = SDIO_DEVICE_ID_MARVELL_8688BT, | ||
64 | .helper = "sd8688_helper.bin", | ||
65 | .firmware = "sd8688.bin", | ||
66 | }, | ||
67 | }; | 61 | }; |
68 | 62 | ||
63 | MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids); | ||
64 | |||
69 | static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) | 65 | static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) |
70 | { | 66 | { |
71 | u8 reg; | 67 | u8 reg; |
@@ -125,7 +121,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) | |||
125 | } | 121 | } |
126 | 122 | ||
127 | static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, | 123 | static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, |
128 | u8 mask) | 124 | u8 mask) |
129 | { | 125 | { |
130 | int ret; | 126 | int ret; |
131 | 127 | ||
@@ -143,7 +139,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, | |||
143 | } | 139 | } |
144 | 140 | ||
145 | static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, | 141 | static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, |
146 | u8 mask) | 142 | u8 mask) |
147 | { | 143 | { |
148 | int ret; | 144 | int ret; |
149 | u8 host_int_mask; | 145 | u8 host_int_mask; |
@@ -203,7 +199,7 @@ done: | |||
203 | } | 199 | } |
204 | 200 | ||
205 | static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, | 201 | static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, |
206 | int pollnum) | 202 | int pollnum) |
207 | { | 203 | { |
208 | int ret = -ETIMEDOUT; | 204 | int ret = -ETIMEDOUT; |
209 | u16 firmwarestat; | 205 | u16 firmwarestat; |
@@ -242,10 +238,10 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
242 | BT_DBG("Enter"); | 238 | BT_DBG("Enter"); |
243 | 239 | ||
244 | ret = request_firmware(&fw_helper, card->helper, | 240 | ret = request_firmware(&fw_helper, card->helper, |
245 | &card->func->dev); | 241 | &card->func->dev); |
246 | if ((ret < 0) || !fw_helper) { | 242 | if ((ret < 0) || !fw_helper) { |
247 | BT_ERR("request_firmware(helper) failed, error code = %d", | 243 | BT_ERR("request_firmware(helper) failed, error code = %d", |
248 | ret); | 244 | ret); |
249 | ret = -ENOENT; | 245 | ret = -ENOENT; |
250 | goto done; | 246 | goto done; |
251 | } | 247 | } |
@@ -254,7 +250,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
254 | helperlen = fw_helper->size; | 250 | helperlen = fw_helper->size; |
255 | 251 | ||
256 | BT_DBG("Downloading helper image (%d bytes), block size %d bytes", | 252 | BT_DBG("Downloading helper image (%d bytes), block size %d bytes", |
257 | helperlen, SDIO_BLOCK_SIZE); | 253 | helperlen, SDIO_BLOCK_SIZE); |
258 | 254 | ||
259 | tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); | 255 | tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); |
260 | 256 | ||
@@ -301,10 +297,8 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
301 | tx_len); | 297 | tx_len); |
302 | 298 | ||
303 | /* Now send the data */ | 299 | /* Now send the data */ |
304 | ret = sdio_writesb(card->func, card->ioport, | 300 | ret = sdio_writesb(card->func, card->ioport, helperbuf, |
305 | helperbuf, | 301 | FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE); |
306 | FIRMWARE_TRANSFER_NBLOCK * | ||
307 | SDIO_BLOCK_SIZE); | ||
308 | if (ret < 0) { | 302 | if (ret < 0) { |
309 | BT_ERR("IO error during helper download @ %d", | 303 | BT_ERR("IO error during helper download @ %d", |
310 | hlprblknow); | 304 | hlprblknow); |
@@ -319,7 +313,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | |||
319 | memset(helperbuf, 0x0, SDIO_BLOCK_SIZE); | 313 | memset(helperbuf, 0x0, SDIO_BLOCK_SIZE); |
320 | 314 | ||
321 | ret = sdio_writesb(card->func, card->ioport, helperbuf, | 315 | ret = sdio_writesb(card->func, card->ioport, helperbuf, |
322 | SDIO_BLOCK_SIZE); | 316 | SDIO_BLOCK_SIZE); |
323 | if (ret < 0) { | 317 | if (ret < 0) { |
324 | BT_ERR("IO error in writing helper image EOF block"); | 318 | BT_ERR("IO error in writing helper image EOF block"); |
325 | goto done; | 319 | goto done; |
@@ -352,10 +346,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
352 | BT_DBG("Enter"); | 346 | BT_DBG("Enter"); |
353 | 347 | ||
354 | ret = request_firmware(&fw_firmware, card->firmware, | 348 | ret = request_firmware(&fw_firmware, card->firmware, |
355 | &card->func->dev); | 349 | &card->func->dev); |
356 | if ((ret < 0) || !fw_firmware) { | 350 | if ((ret < 0) || !fw_firmware) { |
357 | BT_ERR("request_firmware(firmware) failed, error code = %d", | 351 | BT_ERR("request_firmware(firmware) failed, error code = %d", |
358 | ret); | 352 | ret); |
359 | ret = -ENOENT; | 353 | ret = -ENOENT; |
360 | goto done; | 354 | goto done; |
361 | } | 355 | } |
@@ -383,10 +377,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
383 | offset = 0; | 377 | offset = 0; |
384 | do { | 378 | do { |
385 | ret = btmrvl_sdio_poll_card_status(card, | 379 | ret = btmrvl_sdio_poll_card_status(card, |
386 | CARD_IO_READY | DN_LD_CARD_RDY); | 380 | CARD_IO_READY | DN_LD_CARD_RDY); |
387 | if (ret < 0) { | 381 | if (ret < 0) { |
388 | BT_ERR("FW download with helper poll status" | 382 | BT_ERR("FW download with helper poll status" |
389 | " timeout @ %d", offset); | 383 | " timeout @ %d", offset); |
390 | goto done; | 384 | goto done; |
391 | } | 385 | } |
392 | 386 | ||
@@ -427,7 +421,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
427 | break; | 421 | break; |
428 | else if (len > BTM_UPLD_SIZE) { | 422 | else if (len > BTM_UPLD_SIZE) { |
429 | BT_ERR("FW download failure @%d, invalid length %d", | 423 | BT_ERR("FW download failure @%d, invalid length %d", |
430 | offset, len); | 424 | offset, len); |
431 | ret = -EINVAL; | 425 | ret = -EINVAL; |
432 | goto done; | 426 | goto done; |
433 | } | 427 | } |
@@ -465,9 +459,9 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
465 | 459 | ||
466 | if (ret < 0) { | 460 | if (ret < 0) { |
467 | BT_ERR("FW download, writesb(%d) failed @%d", | 461 | BT_ERR("FW download, writesb(%d) failed @%d", |
468 | count, offset); | 462 | count, offset); |
469 | sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, | 463 | sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, |
470 | &ret); | 464 | &ret); |
471 | if (ret) | 465 | if (ret) |
472 | BT_ERR("writeb failed (CFG)"); | 466 | BT_ERR("writeb failed (CFG)"); |
473 | } | 467 | } |
@@ -520,7 +514,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | |||
520 | buf_block_len = (buf_len + blksz - 1) / blksz; | 514 | buf_block_len = (buf_len + blksz - 1) / blksz; |
521 | 515 | ||
522 | if (buf_len <= SDIO_HEADER_LEN | 516 | if (buf_len <= SDIO_HEADER_LEN |
523 | || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { | 517 | || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { |
524 | BT_ERR("invalid packet length: %d", buf_len); | 518 | BT_ERR("invalid packet length: %d", buf_len); |
525 | ret = -EINVAL; | 519 | ret = -EINVAL; |
526 | goto exit; | 520 | goto exit; |
@@ -528,7 +522,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | |||
528 | 522 | ||
529 | /* Allocate buffer */ | 523 | /* Allocate buffer */ |
530 | skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, | 524 | skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, |
531 | GFP_ATOMIC); | 525 | GFP_ATOMIC); |
532 | if (skb == NULL) { | 526 | if (skb == NULL) { |
533 | BT_ERR("No free skb"); | 527 | BT_ERR("No free skb"); |
534 | goto exit; | 528 | goto exit; |
@@ -588,7 +582,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | |||
588 | default: | 582 | default: |
589 | BT_ERR("Unknow packet type:%d", type); | 583 | BT_ERR("Unknow packet type:%d", type); |
590 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, | 584 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, |
591 | blksz * buf_block_len); | 585 | blksz * buf_block_len); |
592 | 586 | ||
593 | kfree_skb(skb); | 587 | kfree_skb(skb); |
594 | skb = NULL; | 588 | skb = NULL; |
@@ -691,9 +685,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) | |||
691 | 685 | ||
692 | static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | 686 | static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) |
693 | { | 687 | { |
694 | int ret = 0, i; | ||
695 | u8 reg; | ||
696 | struct sdio_func *func; | 688 | struct sdio_func *func; |
689 | u8 reg; | ||
690 | int ret = 0; | ||
697 | 691 | ||
698 | BT_DBG("Enter"); | 692 | BT_DBG("Enter"); |
699 | 693 | ||
@@ -705,20 +699,6 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
705 | 699 | ||
706 | func = card->func; | 700 | func = card->func; |
707 | 701 | ||
708 | for (i = 0; i < ARRAY_SIZE(btmrvl_sdio_devices); i++) { | ||
709 | if (func->device == btmrvl_sdio_devices[i].dev_id) | ||
710 | break; | ||
711 | } | ||
712 | |||
713 | if (i == ARRAY_SIZE(btmrvl_sdio_devices)) { | ||
714 | BT_ERR("Error: unknown device id 0x%x", func->device); | ||
715 | ret = -EINVAL; | ||
716 | goto failed; | ||
717 | } | ||
718 | |||
719 | card->helper = btmrvl_sdio_devices[i].helper; | ||
720 | card->firmware = btmrvl_sdio_devices[i].firmware; | ||
721 | |||
722 | sdio_claim_host(func); | 702 | sdio_claim_host(func); |
723 | 703 | ||
724 | ret = sdio_enable_func(func); | 704 | ret = sdio_enable_func(func); |
@@ -983,7 +963,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) | |||
983 | } | 963 | } |
984 | 964 | ||
985 | static int btmrvl_sdio_probe(struct sdio_func *func, | 965 | static int btmrvl_sdio_probe(struct sdio_func *func, |
986 | const struct sdio_device_id *id) | 966 | const struct sdio_device_id *id) |
987 | { | 967 | { |
988 | int ret = 0; | 968 | int ret = 0; |
989 | struct btmrvl_private *priv = NULL; | 969 | struct btmrvl_private *priv = NULL; |
@@ -1002,6 +982,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
1002 | 982 | ||
1003 | card->func = func; | 983 | card->func = func; |
1004 | 984 | ||
985 | if (id->driver_data) { | ||
986 | struct btmrvl_sdio_device *data = (void *) id->driver_data; | ||
987 | card->helper = data->helper; | ||
988 | card->firmware = data->firmware; | ||
989 | } | ||
990 | |||
1005 | if (btmrvl_sdio_register_dev(card) < 0) { | 991 | if (btmrvl_sdio_register_dev(card) < 0) { |
1006 | BT_ERR("Failed to register BT device!"); | 992 | BT_ERR("Failed to register BT device!"); |
1007 | ret = -ENODEV; | 993 | ret = -ENODEV; |
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h index 6beb340685e3..2dd284e0df14 100644 --- a/drivers/bluetooth/btmrvl_sdio.h +++ b/drivers/bluetooth/btmrvl_sdio.h | |||
@@ -90,7 +90,6 @@ struct btmrvl_sdio_card { | |||
90 | }; | 90 | }; |
91 | 91 | ||
92 | struct btmrvl_sdio_device { | 92 | struct btmrvl_sdio_device { |
93 | unsigned short dev_id; | ||
94 | const char *helper; | 93 | const char *helper; |
95 | const char *firmware; | 94 | const char *firmware; |
96 | }; | 95 | }; |