Commit dcf47f3b authored by Marcel Holtmann's avatar Marcel Holtmann

Bluetooth: Fix complicated assignment of firmware for Marvell devices

The Marvell Bluetooth SDIO driver has a really complicated concept on how
firmware names are assigned to specific device ids. Fix that by doing a
proper structure and assign it to the module device table.

And while at it fix various coding style weirdness that is still present
in this driver.
Signed-off-by: default avatarMarcel Holtman <marcel@holtmann.org>
parent 4271e08d
...@@ -31,10 +31,6 @@ ...@@ -31,10 +31,6 @@
#define VERSION "1.0" #define VERSION "1.0"
#ifndef SDIO_DEVICE_ID_MARVELL_8688BT
#define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105
#endif
/* The btmrvl_sdio_remove() callback function is called /* The btmrvl_sdio_remove() callback function is called
* when user removes this module from kernel space or ejects * when user removes this module from kernel space or ejects
* the card from the slot. The driver handles these 2 cases * the card from the slot. The driver handles these 2 cases
...@@ -51,21 +47,21 @@ ...@@ -51,21 +47,21 @@
*/ */
static u8 user_rmmod; static u8 user_rmmod;
static const struct sdio_device_id btmrvl_sdio_ids[] = { static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8688BT)}, .helper = "sd8688_helper.bin",
{0, 0, 0, 0} .firmware = "sd8688.bin",
}; };
MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids); static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
.driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
static struct btmrvl_sdio_device btmrvl_sdio_devices[] = { { } /* Terminating entry */
{
.dev_id = SDIO_DEVICE_ID_MARVELL_8688BT,
.helper = "sd8688_helper.bin",
.firmware = "sd8688.bin",
},
}; };
MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids);
static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
{ {
u8 reg; u8 reg;
...@@ -125,7 +121,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) ...@@ -125,7 +121,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
} }
static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
u8 mask) u8 mask)
{ {
int ret; int ret;
...@@ -143,7 +139,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, ...@@ -143,7 +139,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
} }
static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
u8 mask) u8 mask)
{ {
int ret; int ret;
u8 host_int_mask; u8 host_int_mask;
...@@ -203,7 +199,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits) ...@@ -203,7 +199,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
} }
static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
int pollnum) int pollnum)
{ {
int ret = -ETIMEDOUT; int ret = -ETIMEDOUT;
u16 firmwarestat; u16 firmwarestat;
...@@ -242,10 +238,10 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) ...@@ -242,10 +238,10 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
BT_DBG("Enter"); BT_DBG("Enter");
ret = request_firmware(&fw_helper, card->helper, ret = request_firmware(&fw_helper, card->helper,
&card->func->dev); &card->func->dev);
if ((ret < 0) || !fw_helper) { if ((ret < 0) || !fw_helper) {
BT_ERR("request_firmware(helper) failed, error code = %d", BT_ERR("request_firmware(helper) failed, error code = %d",
ret); ret);
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
...@@ -254,7 +250,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) ...@@ -254,7 +250,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
helperlen = fw_helper->size; helperlen = fw_helper->size;
BT_DBG("Downloading helper image (%d bytes), block size %d bytes", BT_DBG("Downloading helper image (%d bytes), block size %d bytes",
helperlen, SDIO_BLOCK_SIZE); helperlen, SDIO_BLOCK_SIZE);
tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
...@@ -301,10 +297,8 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) ...@@ -301,10 +297,8 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
tx_len); tx_len);
/* Now send the data */ /* Now send the data */
ret = sdio_writesb(card->func, card->ioport, ret = sdio_writesb(card->func, card->ioport, helperbuf,
helperbuf, FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE);
FIRMWARE_TRANSFER_NBLOCK *
SDIO_BLOCK_SIZE);
if (ret < 0) { if (ret < 0) {
BT_ERR("IO error during helper download @ %d", BT_ERR("IO error during helper download @ %d",
hlprblknow); hlprblknow);
...@@ -319,7 +313,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) ...@@ -319,7 +313,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
memset(helperbuf, 0x0, SDIO_BLOCK_SIZE); memset(helperbuf, 0x0, SDIO_BLOCK_SIZE);
ret = sdio_writesb(card->func, card->ioport, helperbuf, ret = sdio_writesb(card->func, card->ioport, helperbuf,
SDIO_BLOCK_SIZE); SDIO_BLOCK_SIZE);
if (ret < 0) { if (ret < 0) {
BT_ERR("IO error in writing helper image EOF block"); BT_ERR("IO error in writing helper image EOF block");
goto done; goto done;
...@@ -352,10 +346,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) ...@@ -352,10 +346,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
BT_DBG("Enter"); BT_DBG("Enter");
ret = request_firmware(&fw_firmware, card->firmware, ret = request_firmware(&fw_firmware, card->firmware,
&card->func->dev); &card->func->dev);
if ((ret < 0) || !fw_firmware) { if ((ret < 0) || !fw_firmware) {
BT_ERR("request_firmware(firmware) failed, error code = %d", BT_ERR("request_firmware(firmware) failed, error code = %d",
ret); ret);
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
...@@ -383,10 +377,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) ...@@ -383,10 +377,10 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
offset = 0; offset = 0;
do { do {
ret = btmrvl_sdio_poll_card_status(card, ret = btmrvl_sdio_poll_card_status(card,
CARD_IO_READY | DN_LD_CARD_RDY); CARD_IO_READY | DN_LD_CARD_RDY);
if (ret < 0) { if (ret < 0) {
BT_ERR("FW download with helper poll status" BT_ERR("FW download with helper poll status"
" timeout @ %d", offset); " timeout @ %d", offset);
goto done; goto done;
} }
...@@ -427,7 +421,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) ...@@ -427,7 +421,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
break; break;
else if (len > BTM_UPLD_SIZE) { else if (len > BTM_UPLD_SIZE) {
BT_ERR("FW download failure @%d, invalid length %d", BT_ERR("FW download failure @%d, invalid length %d",
offset, len); offset, len);
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
} }
...@@ -465,9 +459,9 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) ...@@ -465,9 +459,9 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
if (ret < 0) { if (ret < 0) {
BT_ERR("FW download, writesb(%d) failed @%d", BT_ERR("FW download, writesb(%d) failed @%d",
count, offset); count, offset);
sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG,
&ret); &ret);
if (ret) if (ret)
BT_ERR("writeb failed (CFG)"); BT_ERR("writeb failed (CFG)");
} }
...@@ -520,7 +514,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -520,7 +514,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
buf_block_len = (buf_len + blksz - 1) / blksz; buf_block_len = (buf_len + blksz - 1) / blksz;
if (buf_len <= SDIO_HEADER_LEN if (buf_len <= SDIO_HEADER_LEN
|| (buf_block_len * blksz) > ALLOC_BUF_SIZE) { || (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
BT_ERR("invalid packet length: %d", buf_len); BT_ERR("invalid packet length: %d", buf_len);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
...@@ -528,7 +522,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -528,7 +522,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
/* Allocate buffer */ /* Allocate buffer */
skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN,
GFP_ATOMIC); GFP_ATOMIC);
if (skb == NULL) { if (skb == NULL) {
BT_ERR("No free skb"); BT_ERR("No free skb");
goto exit; goto exit;
...@@ -588,7 +582,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -588,7 +582,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
default: default:
BT_ERR("Unknow packet type:%d", type); BT_ERR("Unknow packet type:%d", type);
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
blksz * buf_block_len); blksz * buf_block_len);
kfree_skb(skb); kfree_skb(skb);
skb = NULL; skb = NULL;
...@@ -691,9 +685,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) ...@@ -691,9 +685,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
{ {
int ret = 0, i;
u8 reg;
struct sdio_func *func; struct sdio_func *func;
u8 reg;
int ret = 0;
BT_DBG("Enter"); BT_DBG("Enter");
...@@ -705,20 +699,6 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) ...@@ -705,20 +699,6 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
func = card->func; func = card->func;
for (i = 0; i < ARRAY_SIZE(btmrvl_sdio_devices); i++) {
if (func->device == btmrvl_sdio_devices[i].dev_id)
break;
}
if (i == ARRAY_SIZE(btmrvl_sdio_devices)) {
BT_ERR("Error: unknown device id 0x%x", func->device);
ret = -EINVAL;
goto failed;
}
card->helper = btmrvl_sdio_devices[i].helper;
card->firmware = btmrvl_sdio_devices[i].firmware;
sdio_claim_host(func); sdio_claim_host(func);
ret = sdio_enable_func(func); ret = sdio_enable_func(func);
...@@ -983,7 +963,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) ...@@ -983,7 +963,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
} }
static int btmrvl_sdio_probe(struct sdio_func *func, static int btmrvl_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
int ret = 0; int ret = 0;
struct btmrvl_private *priv = NULL; struct btmrvl_private *priv = NULL;
...@@ -1002,6 +982,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func, ...@@ -1002,6 +982,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
card->func = func; card->func = func;
if (id->driver_data) {
struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper;
card->firmware = data->firmware;
}
if (btmrvl_sdio_register_dev(card) < 0) { if (btmrvl_sdio_register_dev(card) < 0) {
BT_ERR("Failed to register BT device!"); BT_ERR("Failed to register BT device!");
ret = -ENODEV; ret = -ENODEV;
......
...@@ -90,7 +90,6 @@ struct btmrvl_sdio_card { ...@@ -90,7 +90,6 @@ struct btmrvl_sdio_card {
}; };
struct btmrvl_sdio_device { struct btmrvl_sdio_device {
unsigned short dev_id;
const char *helper; const char *helper;
const char *firmware; const char *firmware;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment