libertas: Add auto deep sleep support for SD8385/SD8686/SD8688

Add timer based auto deep sleep feature in libertas driver which can be
configured using iwconfig command. This is tested on SD8688, SD8686 cards
with firmware versions 10.38.1.p25, 9.70.4.p0 respectively on 32-bit and 64-bit
platforms. Tests have been done for USB/CS cards to make sure that the patch
won't break USB/CS code. We didn't test the if_spi driver.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Amitkumar Karwar
2009-09-30 20:04:38 -07:00
committed by John W. Linville
parent 125b181aec
commit 4912545472
15 changed files with 533 additions and 21 deletions

View File

@@ -831,6 +831,58 @@ out:
return ret;
}
static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
{
int ret = -1;
struct cmd_header cmd;
memset(&cmd, 0, sizeof(cmd));
lbs_deb_sdio("send DEEP_SLEEP command\n");
ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
lbs_cmd_copyback, (unsigned long) &cmd);
if (ret)
lbs_pr_err("DEEP_SLEEP cmd failed\n");
mdelay(200);
return ret;
}
static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
{
struct if_sdio_card *card = priv->card;
int ret = -1;
lbs_deb_enter(LBS_DEB_SDIO);
sdio_claim_host(card->func);
sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
if (ret)
lbs_pr_err("sdio_writeb failed!\n");
sdio_release_host(card->func);
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
}
static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
{
struct if_sdio_card *card = priv->card;
int ret = -1;
lbs_deb_enter(LBS_DEB_SDIO);
sdio_claim_host(card->func);
sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
if (ret)
lbs_pr_err("sdio_writeb failed!\n");
sdio_release_host(card->func);
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
}
/*******************************************************************/
/* SDIO callbacks */
/*******************************************************************/
@@ -859,6 +911,7 @@ static void if_sdio_interrupt(struct sdio_func *func)
* Ignore the define name, this really means the card has
* successfully received the command.
*/
card->priv->is_activity_detected = 1;
if (cause & IF_SDIO_H_INT_DNLD)
lbs_host_to_card_done(card->priv);
@@ -998,6 +1051,9 @@ static int if_sdio_probe(struct sdio_func *func,
priv->card = card;
priv->hw_host_to_card = if_sdio_host_to_card;
priv->enter_deep_sleep = if_sdio_enter_deep_sleep;
priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
priv->fw_ready = 1;