[PATCH 1/2] libertas_spi: Implement deep sleep for SPI interface
Thomas Pedersen
thomas at cozybit.com
Wed Jul 6 22:29:10 EDT 2011
This patch implements deep sleep functionality for the 8686 SPI
interface. Currently, only the SPI register wakeup trigger is used.
Signed-off-by: Thomas Pedersen <thomas at cozybit.com>
---
drivers/net/wireless/libertas/if_spi.c | 60 ++++++++++++++++++++++++++++++--
1 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index d041bb2..d2026cc 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -32,6 +32,7 @@
#include "decl.h"
#include "defs.h"
#include "dev.h"
+#include "cmd.h"
#include "if_spi.h"
struct if_spi_packet {
@@ -875,6 +876,8 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
lbs_deb_enter(LBS_DEB_SPI);
+ card->priv->is_activity_detected = 1;
+
/*
* Read the host interrupt status register to see what we
* can do.
@@ -1029,6 +1032,57 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
* SPI callbacks
*/
+static int if_spi_enter_deep_sleep(struct lbs_private *priv)
+{
+ int ret = -1;
+ struct cmd_header cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ lbs_deb_spi("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)
+ netdev_err(priv->dev, "DEEP_SLEEP cmd failed\n");
+
+ mdelay(200);
+ return ret;
+}
+
+static int if_spi_exit_deep_sleep(struct lbs_private *priv)
+{
+ struct if_spi_card *card = priv->card;
+ int ret = -1;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ ret = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
+ IF_SPI_HICT_WAKE_UP);
+ if (ret)
+ netdev_err(priv->dev, "spu write failed!\n");
+
+ lbs_deb_leave_args(LBS_DEB_SPI, "ret %d", ret);
+ return ret;
+}
+
+static int if_spi_reset_deep_sleep_wakeup(struct lbs_private *priv)
+{
+ struct if_spi_card *card = priv->card;
+ int ret = -1;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ ret = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, 0);
+ if (ret)
+ netdev_err(priv->dev, "spu write failed!\n");
+ /* FW seems to forget which interrupts were enabled */
+ spu_set_interrupt_mode(card, 0, 1);
+
+ lbs_deb_leave_args(LBS_DEB_SPI, "ret %d", ret);
+ return ret;
+
+}
+
static int if_spi_init_card(struct if_spi_card *card)
{
struct lbs_private *priv = card->priv;
@@ -1183,9 +1237,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
priv->setup_fw_on_resume = 1;
priv->card = card;
priv->hw_host_to_card = if_spi_host_to_card;
- priv->enter_deep_sleep = NULL;
- priv->exit_deep_sleep = NULL;
- priv->reset_deep_sleep_wakeup = NULL;
+ priv->enter_deep_sleep = if_spi_enter_deep_sleep;
+ priv->exit_deep_sleep = if_spi_exit_deep_sleep;
+ priv->reset_deep_sleep_wakeup = if_spi_reset_deep_sleep_wakeup;
priv->fw_ready = 1;
/* Initialize interrupt handling stuff. */
--
1.7.6
More information about the libertas-dev
mailing list