1// SPDX-License-Identifier: GPL-2.0
2/******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7/*++
8Copyright (c) Realtek Semiconductor Corp. All rights reserved.
9
10Module Name:
11	HalPwrSeqCmd.c
12
13Abstract:
14	Implement HW Power sequence configuration CMD handling routine for Realtek devices.
15
16Major Change History:
17	When       Who               What
18	---------- ---------------   -------------------------------
19	2011-10-26 Lucas            Modify to be compatible with SD4-CE driver.
20	2011-07-07 Roger            Create.
21
22--*/
23#include <drv_types.h>
24#include <rtw_debug.h>
25#include <HalPwrSeqCmd.h>
26
27
28/*  */
29/*  Description: */
30/*  This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. */
31/*  */
32/*  Assumption: */
33/*  We should follow specific format which was released from HW SD. */
34/*  */
35/*  2011.07.07, added by Roger. */
36/*  */
37u8 HalPwrSeqCmdParsing(
38	struct adapter *padapter,
39	u8 CutVersion,
40	u8 FabVersion,
41	u8 InterfaceType,
42	struct wlan_pwr_cfg PwrSeqCmd[]
43)
44{
45	struct wlan_pwr_cfg PwrCfgCmd;
46	u8 bPollingBit = false;
47	u32 AryIdx = 0;
48	u8 value = 0;
49	u32 offset = 0;
50	u32 pollingCount = 0; /*  polling autoload done. */
51	u32 maxPollingCnt = 5000;
52
53	do {
54		PwrCfgCmd = PwrSeqCmd[AryIdx];
55
56		/* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
57		if (
58			(GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
59			(GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
60			(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)
61		) {
62			switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
63			case PWR_CMD_READ:
64				break;
65
66			case PWR_CMD_WRITE:
67				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
68
69				/*  */
70				/*  <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
71				/*  2011.07.07. */
72				/*  */
73				if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
74					/*  Read Back SDIO Local value */
75					value = SdioLocalCmd52Read1Byte(padapter, offset);
76
77					value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
78					value |= (
79						GET_PWR_CFG_VALUE(PwrCfgCmd) &
80						GET_PWR_CFG_MASK(PwrCfgCmd)
81					);
82
83					/*  Write Back SDIO Local value */
84					SdioLocalCmd52Write1Byte(padapter, offset, value);
85				} else {
86					/*  Read the value from system register */
87					value = rtw_read8(padapter, offset);
88
89					value &= (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
90					value |= (
91						GET_PWR_CFG_VALUE(PwrCfgCmd)
92						&GET_PWR_CFG_MASK(PwrCfgCmd)
93					);
94
95					/*  Write the value back to system register */
96					rtw_write8(padapter, offset, value);
97				}
98				break;
99
100			case PWR_CMD_POLLING:
101
102				bPollingBit = false;
103				offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
104				do {
105					if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
106						value = SdioLocalCmd52Read1Byte(padapter, offset);
107					else
108						value = rtw_read8(padapter, offset);
109
110					value = value&GET_PWR_CFG_MASK(PwrCfgCmd);
111					if (
112						value == (GET_PWR_CFG_VALUE(PwrCfgCmd) &
113						GET_PWR_CFG_MASK(PwrCfgCmd))
114					)
115						bPollingBit = true;
116					else
117						udelay(10);
118
119					if (pollingCount++ > maxPollingCnt)
120						return false;
121
122				} while (!bPollingBit);
123
124				break;
125
126			case PWR_CMD_DELAY:
127				if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
128					udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd));
129				else
130					udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000);
131				break;
132
133			case PWR_CMD_END:
134				/*  When this command is parsed, end the process */
135				return true;
136
137			default:
138				break;
139			}
140		}
141
142		AryIdx++;/* Add Array Index */
143	} while (1);
144
145	return true;
146}
147