Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1#include "headers.h"
  2
  3/*
  4Function:				InterfaceIdleModeWakeup
  5
  6Description:			This is the hardware specific Function for waking up HW device from Idle mode.
  7						A software abort pattern is written to the device to wake it and necessary power state
  8						transitions from host are performed here.
  9
 10Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
 11
 12
 13Return:				BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful.
 14						Other           - If an error occurred.
 15*/
 16
 17
 18/*
 19Function:				InterfaceIdleModeRespond
 20
 21Description:			This is the hardware specific Function for responding to Idle mode request from target.
 22						Necessary power state transitions from host for idle mode or other device specific
 23						initializations are performed here.
 24
 25Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
 26
 27
 28Return:				BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful.
 29						Other           - If an error occurred.
 30*/
 31
 32/*
 33"dmem bfc02f00  100" tells how many time device went in Idle mode.
 34this value will be at address bfc02fa4.just before value d0ea1dle.
 35
 36Set time value by writing at bfc02f98 7d0
 37
 38checking the Ack timer expire on kannon by running command
 39d qcslog .. if it shows e means host has not send response to f/w with in 200 ms. Response should be
 40send to f/w with in 200 ms after the Idle/Shutdown req issued
 41
 42*/
 43
 44
 45int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer)
 46{
 47	int	status = STATUS_SUCCESS;
 48	unsigned int	uiRegRead = 0;
 49
 50	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"SubType of Message :0x%X", ntohl(*puiBuffer));
 51
 52	if(ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD)
 53	{
 54		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL," Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype");
 55		if(ntohl(*(puiBuffer+1)) == 0 )
 56		{
 57			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Got IDLE MODE WAKE UP Response From F/W");
 58
 59			status = wrmalt (Adapter,SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead));
 60			if(status)
 61			{
 62				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg");
 63				return status;
 64			}
 65
 66			if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
 67			{
 68				uiRegRead = 0x00000000 ;
 69				status = wrmalt (Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead));
 70				if(status)
 71				{
 72					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode	Reg");
 73					return status;
 74				}
 75			}
 76			//Below Register should not br read in case of Manual and Protocol Idle mode.
 77			else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
 78			{
 79				//clear on read Register
 80				status = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead));
 81				if(status)
 82				{
 83					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0");
 84					return status;
 85				}
 86				//clear on read Register
 87				status = rdmalt (Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead));
 88				if(status)
 89				{
 90					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort	Reg1");
 91					return status;
 92				}
 93			}
 94			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode");
 95
 96			// Set Idle Mode Flag to False and Clear IdleMode reg.
 97			Adapter->IdleMode = FALSE;
 98			Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
 99
100			wake_up(&Adapter->lowpower_mode_wait_queue);
101
102		}
103		else
104		{
105			if(TRUE == Adapter->IdleMode)
106			{
107				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Device is already in Idle mode....");
108				return status ;
109			}
110
111			uiRegRead = 0;
112			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n");
113
114			if (Adapter->chip_id== BCS220_2 ||
115				Adapter->chip_id == BCS220_2BC ||
116					Adapter->chip_id== BCS250_BC ||
117					Adapter->chip_id== BCS220_3)
118			{
119
120				status = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
121				if(status)
122				{
123					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n");
124					return status;
125				}
126
127
128				uiRegRead |= (1<<17);
129
130				status = wrmalt (Adapter,HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
131				if(status)
132				{
133					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n");
134					return status;
135				}
136
137			}
138			SendIdleModeResponse(Adapter);
139		}
140	}
141	else if(ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG)
142	{
143		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params");
144		OverrideServiceFlowParams(Adapter,puiBuffer);
145	}
146	return status;
147}
148
149static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
150{
151	int 	status = STATUS_SUCCESS;
152	unsigned int value;
153	unsigned int chip_id ;
154	unsigned long timeout = 0 ,itr = 0;
155
156	int 	lenwritten = 0;
157	unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
158	PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter;
159
160	//Abort Bus suspend if its already suspended
161	if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))
162	{
163		status = usb_autopm_get_interface(psInterfaceAdapter->interface);
164		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Bus got wakeup..Aborting Idle mode... status:%d \n",status);
165
166	}
167
168	if((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
169									||
170	   (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE))
171	{
172		//write the SW abort pattern.
173		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern);
174		status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern));
175		if(status)
176		{
177				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
178				return status;
179		}
180	}
181
182	if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
183	{
184		value = 0x80000000;
185		status = wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value));
186		if(status)
187		{
188			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed");
189			return status;
190		}
191	}
192	else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
193	{
194		/*
195		 * Get a Interrupt Out URB and send 8 Bytes Down
196		 * To be Done in Thread Context.
197		 * Not using Asynchronous Mechanism.
198		 */
199		status = usb_interrupt_msg (psInterfaceAdapter->udev,
200			usb_sndintpipe(psInterfaceAdapter->udev,
201			psInterfaceAdapter->sIntrOut.int_out_endpointAddr),
202			aucAbortPattern,
203			8,
204			&lenwritten,
205			5000);
206		if(status)
207		{
208			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n",status);
209			return status;
210		}
211		else
212		{
213			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten);
214		}
215
216		//mdelay(25);
217
218		timeout= jiffies +  msecs_to_jiffies(50) ;
219		while( timeout > jiffies )
220		{
221			itr++ ;
222			rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT));
223			if(0xbece3200==(chip_id&~(0xF0)))
224			{
225				chip_id = chip_id&~(0xF0);
226			}
227			if(chip_id == Adapter->chip_id)
228				break;
229		}
230		if(timeout < jiffies )
231		{
232			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Not able to read chip-id even after 25 msec");
233		}
234		else
235		{
236			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Number of completed iteration to read chip-id :%lu", itr);
237		}
238
239		status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status));
240		if(status)
241		{
242			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
243			return status;
244		}
245	}
246	return status;
247}
248int InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter)
249{
250	ULONG	Status = 0;
251	if(Adapter->bTriedToWakeUpFromlowPowerMode)
252	{
253		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n");
254	}
255	else
256	{
257		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Writing Low Power Mode Abort pattern to the Device\n");
258		Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
259		InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern);
260
261	}
262	return Status;
263}
264
265void InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter)
266{
267	unsigned int uiRegVal = 0;
268	INT Status = 0;
269	if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
270	{
271		// clear idlemode interrupt.
272		uiRegVal = 0;
273		Status =wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal));
274		if(Status)
275		{
276			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status);
277			return;
278		}
279	}
280
281    else
282	{
283
284        //clear Interrupt EP registers.
285		Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
286		if(Status)
287		{
288			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status);
289			return;
290		}
291
292        Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
293		if(Status)
294		{
295			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status);
296			return;
297		}
298	}
299}
300