**/
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
u8 reg;
int ret;
- BT_DBG("Enter");
-
reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret);
if (!ret)
card->rx_unit = reg;
- BT_DBG("Leave");
-
return ret;
}
static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
{
- int ret;
u8 fws0, fws1;
-
- BT_DBG("Enter");
+ int ret;
*dat = 0;
if (!ret)
fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
- if (ret) {
- BT_DBG("Leave");
+ if (ret)
return -EIO;
- }
*dat = (((u16) fws1) << 8) | fws0;
- BT_DBG("Leave");
-
return 0;
}
static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
{
- int ret;
u8 reg;
-
- BT_DBG("Enter");
+ int ret;
reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret);
if (!ret)
*dat = (u16) reg << card->rx_unit;
- BT_DBG("Leave");
-
return ret;
}
{
int ret;
- BT_DBG("Enter");
-
sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
if (ret) {
BT_ERR("Unable to enable the host interrupt!");
ret = -EIO;
}
- BT_DBG("Leave");
-
return ret;
}
static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
u8 mask)
{
- int ret;
u8 host_int_mask;
-
- BT_DBG("Enter");
+ int ret;
host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret);
- if (ret) {
- ret = -EIO;
- goto done;
- }
+ if (ret)
+ return -EIO;
host_int_mask &= ~mask;
sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret);
if (ret < 0) {
BT_ERR("Unable to disable the host interrupt!");
- ret = -EIO;
- goto done;
+ return -EIO;
}
- ret = 0;
-
-done:
- BT_DBG("Leave");
-
- return ret;
+ return 0;
}
static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
{
unsigned int tries;
- int ret;
u8 status;
-
- BT_DBG("Enter");
+ int ret;
for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
status = sdio_readb(card->func, CARD_STATUS_REG, &ret);
if (ret)
goto failed;
if ((status & bits) == bits)
- goto done;
+ return ret;
udelay(1);
}
failed:
BT_ERR("FAILED! ret=%d", ret);
-done:
- BT_DBG("Leave");
-
return ret;
}
u16 firmwarestat;
unsigned int tries;
- BT_DBG("Enter");
-
/* Wait for firmware to become ready */
for (tries = 0; tries < pollnum; tries++) {
if (btmrvl_sdio_read_fw_status(card, &firmwarestat) < 0)
}
}
- BT_DBG("Leave");
-
return ret;
}
u8 *helperbuf;
u32 tx_len;
- BT_DBG("Enter");
-
ret = request_firmware(&fw_helper, card->helper,
&card->func->dev);
if ((ret < 0) || !fw_helper) {
if (fw_helper)
release_firmware(fw_helper);
- BT_DBG("Leave");
-
return ret;
}
u16 len;
int txlen = 0, tx_blocks = 0, count = 0;
- BT_DBG("Enter");
-
ret = request_firmware(&fw_firmware, card->firmware,
&card->func->dev);
if ((ret < 0) || !fw_firmware) {
if (fw_firmware)
release_firmware(fw_firmware);
- BT_DBG("Leave");
-
return ret;
}
struct hci_dev *hdev = priv->btmrvl_dev.hcidev;
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
- BT_DBG("Enter");
-
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
ret = -EINVAL;
goto exit;
}
- if ((u32) skb->data & (BTSDIO_DMA_ALIGN - 1)) {
- skb_put(skb, (u32) skb->data & (BTSDIO_DMA_ALIGN - 1));
- skb_pull(skb, (u32) skb->data & (BTSDIO_DMA_ALIGN - 1));
+ if ((unsigned long) skb->data & (BTSDIO_DMA_ALIGN - 1)) {
+ skb_put(skb, (unsigned long) skb->data &
+ (BTSDIO_DMA_ALIGN - 1));
+ skb_pull(skb, (unsigned long) skb->data &
+ (BTSDIO_DMA_ALIGN - 1));
}
- payload = skb->tail;
+ payload = skb->data;
ret = sdio_readsb(card->func, payload, card->ioport,
buf_block_len * blksz);
break;
default:
- BT_ERR("Unknow packet type:%d", type);
+ BT_ERR("Unknown packet type:%d", type);
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
blksz * buf_block_len);
kfree_skb(skb);
}
- BT_DBG("Leave");
-
return ret;
}
u8 sdio_ireg = 0;
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
- BT_DBG("Enter");
-
*ireg = 0;
sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
ret = 0;
done:
- BT_DBG("Leave");
-
return ret;
}
struct btmrvl_sdio_card *card;
u8 ireg = 0;
- BT_DBG("Enter");
-
card = sdio_get_drvdata(func);
if (card && card->priv) {
priv = card->priv;
btmrvl_interrupt(priv);
}
-
- BT_DBG("Leave");
}
static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
u8 reg;
int ret = 0;
- BT_DBG("Enter");
-
if (!card || !card->func) {
BT_ERR("Error: card or function is NULL!");
ret = -EINVAL;
sdio_release_host(func);
- BT_DBG("Leave");
return 0;
release_irq:
sdio_release_host(func);
failed:
- BT_DBG("Leave");
return ret;
}
static int btmrvl_sdio_unregister_dev(struct btmrvl_sdio_card *card)
{
- BT_DBG("Enter");
-
if (card && card->func) {
sdio_claim_host(card->func);
sdio_release_irq(card->func);
sdio_set_drvdata(card->func, NULL);
}
- BT_DBG("Leave");
-
return 0;
}
{
int ret;
- BT_DBG("Enter");
-
- if (!card || !card->func) {
- BT_DBG("Leave");
+ if (!card || !card->func)
return -EINVAL;
- }
sdio_claim_host(card->func);
sdio_release_host(card->func);
- BT_DBG("Leave");
-
return ret;
}
{
int ret;
- BT_DBG("Enter");
-
- if (!card || !card->func) {
- BT_DBG("Leave");
+ if (!card || !card->func)
return -EINVAL;
- }
sdio_claim_host(card->func);
sdio_release_host(card->func);
- BT_DBG("Leave");
-
return ret;
}
void *tmpbuf = NULL;
int tmpbufsz;
- BT_DBG("Enter");
-
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
- BT_DBG("Leave");
return -EINVAL;
}
buf = payload;
- if ((u32) payload & (BTSDIO_DMA_ALIGN - 1)) {
+ if ((unsigned long) payload & (BTSDIO_DMA_ALIGN - 1)) {
tmpbufsz = ALIGN_SZ(nb, BTSDIO_DMA_ALIGN);
- tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL);
- memset(tmpbuf, 0, tmpbufsz);
+ tmpbuf = kzalloc(tmpbufsz, GFP_KERNEL);
+ if (!tmpbuf)
+ return -ENOMEM;
buf = (u8 *) ALIGN_ADDR(tmpbuf, BTSDIO_DMA_ALIGN);
memcpy(buf, payload, nb);
}
exit:
sdio_release_host(card->func);
-
- BT_DBG("Leave");
+ kfree(tmpbuf);
return ret;
}
{
int ret = 0;
- BT_DBG("Enter");
-
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
- BT_DBG("Leave");
return -EINVAL;
}
sdio_claim_host(card->func);
done:
sdio_release_host(card->func);
- BT_DBG("Leave");
-
return ret;
}
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret = 0;
- BT_DBG("Enter");
-
if (!card || !card->func) {
BT_ERR("card or function is NULL!");
- BT_DBG("Leave");
return -EINVAL;
}
BT_DBG("wake up firmware");
- BT_DBG("Leave");
-
return ret;
}
struct btmrvl_private *priv = NULL;
struct btmrvl_sdio_card *card = NULL;
- BT_DBG("Enter");
-
BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d",
id->vendor, id->device, id->class, func->num);
priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
-
- BT_DBG("Leave");
+ priv->btmrvl_dev.psmode = 1;
+ btmrvl_enable_ps(priv);
return 0;
free_card:
kfree(card);
done:
- BT_DBG("Leave");
-
return ret;
}
{
struct btmrvl_sdio_card *card;
- BT_DBG("Enter");
-
if (func) {
card = sdio_get_drvdata(func);
if (card) {
kfree(card);
}
}
-
- BT_DBG("Leave");
}
static struct sdio_driver bt_mrvl_sdio = {
.remove = btmrvl_sdio_remove,
};
-static int btmrvl_sdio_init_module(void)
+static int __init btmrvl_sdio_init_module(void)
{
- BT_DBG("Enter");
-
if (sdio_register_driver(&bt_mrvl_sdio) != 0) {
BT_ERR("SDIO Driver Registration Failed");
- BT_DBG("Leave");
return -ENODEV;
}
/* Clear the flag in case user removes the card. */
user_rmmod = 0;
- BT_DBG("Leave");
-
return 0;
}
-static void btmrvl_sdio_exit_module(void)
+static void __exit btmrvl_sdio_exit_module(void)
{
- BT_DBG("Enter");
-
/* Set the flag as user is removing this module. */
user_rmmod = 1;
sdio_unregister_driver(&bt_mrvl_sdio);
-
- BT_DBG("Leave");
}
module_init(btmrvl_sdio_init_module);
MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
+MODULE_FIRMWARE("sd8688_helper.bin");
+MODULE_FIRMWARE("sd8688.bin");