summaryrefslogtreecommitdiff
path: root/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/r8188eu/hal/HalPwrSeqCmd.c')
-rw-r--r--drivers/staging/r8188eu/hal/HalPwrSeqCmd.c118
1 files changed, 101 insertions, 17 deletions
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 150ea380c39e..6c0b1368383d 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -3,25 +3,116 @@
#include "../include/HalPwrSeqCmd.h"
-u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
+#define PWR_CMD_WRITE 0x01
+ /* offset: the read register offset */
+ /* msk: the mask of the write bits */
+ /* value: write value */
+ /* note: driver shall implement this cmd by read & msk after write */
+
+#define PWR_CMD_POLLING 0x02
+ /* offset: the read register offset */
+ /* msk: the mask of the polled value */
+ /* value: the value to be polled, masked by the msd field. */
+ /* note: driver shall implement this cmd by */
+ /* do{ */
+ /* if ( (Read(offset) & msk) == (value & msk) ) */
+ /* break; */
+ /* } while (not timeout); */
+
+#define PWR_CMD_DELAY 0x03
+ /* offset: the value to delay (in us) */
+ /* msk: N/A */
+ /* value: N/A */
+
+struct wl_pwr_cfg {
+ u16 offset;
+ u8 cmd:4;
+ u8 msk;
+ u8 value;
+};
+
+#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
+#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
+#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
+#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
+
+static struct wl_pwr_cfg rtl8188E_power_on_flow[] = {
+ { 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) },
+ { 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */
+ { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
+ { 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/
+ { 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/
+ { 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) },
+ { 0x0005, PWR_CMD_POLLING, BIT(0), 0 },
+ { 0x0023, PWR_CMD_WRITE, BIT(4), 0 },
+};
+
+static struct wl_pwr_cfg rtl8188E_card_disable_flow[] = {
+ { 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */
+ { 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */
+ { 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */
+ { 0x0005, PWR_CMD_POLLING, BIT(1), 0 },
+ { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
+ { 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */
+ { 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */
+ { 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */
+ { 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */
+};
+
+/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */
+static struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = {
+ { 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */
+ { 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */
+ { 0x0002, PWR_CMD_DELAY, 0, 0 },
+ { 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */
+ { 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */
+ { 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */
+};
+
+u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq)
{
struct wl_pwr_cfg pwrcfgcmd = {0};
+ struct wl_pwr_cfg *pwrseqcmd;
u8 poll_bit = false;
- u32 aryidx = 0;
+ u8 idx, num_steps;
u8 value = 0;
u32 offset = 0;
u32 poll_count = 0; /* polling autoload done. */
u32 max_poll_count = 5000;
+ int res;
+
+ switch (seq) {
+ case PWR_ON_FLOW:
+ pwrseqcmd = rtl8188E_power_on_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_power_on_flow);
+ break;
+ case DISABLE_FLOW:
+ pwrseqcmd = rtl8188E_card_disable_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_card_disable_flow);
+ break;
+ case LPS_ENTER_FLOW:
+ pwrseqcmd = rtl8188E_enter_lps_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_enter_lps_flow);
+ break;
+ default:
+ return false;
+ }
- do {
- pwrcfgcmd = pwrseqcmd[aryidx];
+ for (idx = 0; idx < num_steps; idx++) {
+ pwrcfgcmd = pwrseqcmd[idx];
switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
case PWR_CMD_WRITE:
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
/* Read the value from system register */
- value = rtw_read8(padapter, offset);
+ res = rtw_read8(padapter, offset, &value);
+ if (res)
+ return false;
value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -33,7 +124,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
poll_bit = false;
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
do {
- value = rtw_read8(padapter, offset);
+ res = rtw_read8(padapter, offset, &value);
+ if (res)
+ return false;
value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
@@ -46,20 +139,11 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
} while (!poll_bit);
break;
case PWR_CMD_DELAY:
- if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US)
- udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
- else
- udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000);
- break;
- case PWR_CMD_END:
- /* When this command is parsed, end the process */
- return true;
+ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
break;
default:
break;
}
-
- aryidx++;/* Add Array Index */
- } while (1);
+ }
return true;
}