xref: /openbmc/linux/drivers/staging/vt6656/power.c (revision 6b4c6ce8)
16b4c6ce8SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+
292b96797SForest Bond /*
392b96797SForest Bond  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
492b96797SForest Bond  * All rights reserved.
592b96797SForest Bond  *
692b96797SForest Bond  * This program is free software; you can redistribute it and/or modify
792b96797SForest Bond  * it under the terms of the GNU General Public License as published by
892b96797SForest Bond  * the Free Software Foundation; either version 2 of the License, or
992b96797SForest Bond  * (at your option) any later version.
1092b96797SForest Bond  *
1192b96797SForest Bond  * This program is distributed in the hope that it will be useful,
1292b96797SForest Bond  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1392b96797SForest Bond  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1492b96797SForest Bond  * GNU General Public License for more details.
1592b96797SForest Bond  *
1692b96797SForest Bond  *
1792b96797SForest Bond  * File: power.c
1892b96797SForest Bond  *
190d743951SUwe Kleine-König  * Purpose: Handles 802.11 power management functions
2092b96797SForest Bond  *
2192b96797SForest Bond  * Author: Lyndon Chen
2292b96797SForest Bond  *
2392b96797SForest Bond  * Date: July 17, 2002
2492b96797SForest Bond  *
2592b96797SForest Bond  * Functions:
26c1d45af9SMalcolm Priestley  *      vnt_enable_power_saving - Enable Power Saving Mode
2792b96797SForest Bond  *      PSvDiasblePowerSaving - Disable Power Saving Mode
28bb73fd04SMalcolm Priestley  *      vnt_next_tbtt_wakeup - Decide if we need to wake up at next Beacon
2992b96797SForest Bond  *
3092b96797SForest Bond  * Revision History:
3192b96797SForest Bond  *
3292b96797SForest Bond  */
3392b96797SForest Bond 
3492b96797SForest Bond #include "mac.h"
3592b96797SForest Bond #include "device.h"
3692b96797SForest Bond #include "power.h"
3792b96797SForest Bond #include "wcmd.h"
3892b96797SForest Bond #include "rxtx.h"
3992b96797SForest Bond #include "card.h"
4062c8526dSMalcolm Priestley #include "usbpipe.h"
4192b96797SForest Bond 
427404eab2SPhilip Worrall /*
4392b96797SForest Bond  *
4492b96797SForest Bond  * Routine Description:
4592b96797SForest Bond  * Enable hw power saving functions
4692b96797SForest Bond  *
4792b96797SForest Bond  * Return Value:
4892b96797SForest Bond  *    None.
4992b96797SForest Bond  *
507404eab2SPhilip Worrall  */
5192b96797SForest Bond 
52c1d45af9SMalcolm Priestley void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
5392b96797SForest Bond {
54bbdf1bd4SMalcolm Priestley 	u16 aid = priv->current_aid | BIT(14) | BIT(15);
5592b96797SForest Bond 
564846cbc1SAlejandro Emanuel Paredes 	/* set period of power up before TBTT */
572bac6f98SMalcolm Priestley 	vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT);
5892b96797SForest Bond 
597526a468SAmitoj Kaur Chawla 	if (priv->op_mode != NL80211_IFTYPE_ADHOC)
604846cbc1SAlejandro Emanuel Paredes 		/* set AID */
612bac6f98SMalcolm Priestley 		vnt_mac_write_word(priv, MAC_REG_AIDATIM, aid);
6292b96797SForest Bond 
6364052b78SAybuke Ozdemir 	/* Warren:06-18-2004,the sequence must follow
6464052b78SAybuke Ozdemir 	 * PSEN->AUTOSLEEP->GO2DOZE
6564052b78SAybuke Ozdemir 	 */
667404eab2SPhilip Worrall 	/* enable power saving hw function */
672bac6f98SMalcolm Priestley 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_PSEN);
68f9cfbe94SPhilip Worrall 
697404eab2SPhilip Worrall 	/* Set AutoSleep */
702bac6f98SMalcolm Priestley 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
7192b96797SForest Bond 
7264052b78SAybuke Ozdemir 	/* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the
7364052b78SAybuke Ozdemir 	 * AUTOSLEEP doesn't work
7464052b78SAybuke Ozdemir 	 */
752bac6f98SMalcolm Priestley 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE);
7692b96797SForest Bond 
772bac6f98SMalcolm Priestley 	if (listen_interval >= 2) {
787404eab2SPhilip Worrall 		/* clear always listen beacon */
792bac6f98SMalcolm Priestley 		vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
80f9cfbe94SPhilip Worrall 
817404eab2SPhilip Worrall 		/* first time set listen next beacon */
822bac6f98SMalcolm Priestley 		vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
839e6519bbSSimon Sandström 	} else {
847404eab2SPhilip Worrall 		/* always listen beacon */
852bac6f98SMalcolm Priestley 		vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
869e6519bbSSimon Sandström 	}
8792b96797SForest Bond 
88752b7dafSMalcolm Priestley 	dev_dbg(&priv->usb->dev,  "PS:Power Saving Mode Enable...\n");
8992b96797SForest Bond }
9092b96797SForest Bond 
917404eab2SPhilip Worrall /*
9292b96797SForest Bond  *
9392b96797SForest Bond  * Routine Description:
9492b96797SForest Bond  * Disable hw power saving functions
9592b96797SForest Bond  *
9692b96797SForest Bond  * Return Value:
9792b96797SForest Bond  *    None.
9892b96797SForest Bond  *
997404eab2SPhilip Worrall  */
10092b96797SForest Bond 
101905dba5cSMalcolm Priestley void vnt_disable_power_saving(struct vnt_private *priv)
10292b96797SForest Bond {
1037404eab2SPhilip Worrall 	/* disable power saving hw function */
10438c7b5b5SMalcolm Priestley 	vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0,
105f9cfbe94SPhilip Worrall 			0, 0, NULL);
10692b96797SForest Bond 
1077404eab2SPhilip Worrall 	/* clear AutoSleep */
10838c7b5b5SMalcolm Priestley 	vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
10992b96797SForest Bond 
1107404eab2SPhilip Worrall 	/* set always listen beacon */
11138c7b5b5SMalcolm Priestley 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
11292b96797SForest Bond }
11392b96797SForest Bond 
1147404eab2SPhilip Worrall /*
11592b96797SForest Bond  *
11692b96797SForest Bond  * Routine Description:
11792b96797SForest Bond  * Check if Next TBTT must wake up
11892b96797SForest Bond  *
11992b96797SForest Bond  * Return Value:
12092b96797SForest Bond  *    None.
12192b96797SForest Bond  *
1227404eab2SPhilip Worrall  */
12392b96797SForest Bond 
124bb73fd04SMalcolm Priestley int vnt_next_tbtt_wakeup(struct vnt_private *priv)
12592b96797SForest Bond {
126f7c7f7f2SMalcolm Priestley 	struct ieee80211_hw *hw = priv->hw;
127f7c7f7f2SMalcolm Priestley 	struct ieee80211_conf *conf = &hw->conf;
128bedf4efaSMalcolm Priestley 	int wake_up = false;
12992b96797SForest Bond 
13043c93d9bSMalcolm Priestley 	if (conf->listen_interval > 1) {
1317404eab2SPhilip Worrall 		/* Turn on wake up to listen next beacon */
132bedf4efaSMalcolm Priestley 		vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
133bedf4efaSMalcolm Priestley 		wake_up = true;
13492b96797SForest Bond 	}
13592b96797SForest Bond 
136f7c7f7f2SMalcolm Priestley 	return wake_up;
137f7c7f7f2SMalcolm Priestley }
138