|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // omap3530/omap3530_drivers/usbcc/omap3530_usbc.h |
|
15 // Platform-dependent USB client controller layer (USB PSL). |
|
16 // |
|
17 |
|
18 |
|
19 #ifndef __OMAP3530_USBC_H__ |
|
20 #define __OMAP3530_USBC_H__ |
|
21 |
|
22 #include <e32cmn.h> |
|
23 #include <drivers/usbc.h> |
|
24 #include <assp/omap3530_assp/omap3530_assp_priv.h> |
|
25 |
|
26 // This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client |
|
27 // (device) controller. |
|
28 // For simplicity's sake we assume the following endpoint layout of the controller. |
|
29 // We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT), |
|
30 // one Interrupt endpoint (IN), and of course endpoint zero (Ep0). |
|
31 // |
|
32 // This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also |
|
33 // used as the array index for our local TTemplateAsspUsbcc::iEndpoints[]): |
|
34 // |
|
35 // 0 - 0 (Ep0 OUT) |
|
36 // 0 - 1 (Ep0 IN) |
|
37 // 1 - 3 (Bulk IN, Address 0x11, -> EpAddr2Idx(0x11) = 3) |
|
38 // 2 - 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) = 4) |
|
39 // 3 - 7 (Iso IN, Address 0x13, -> EpAddr2Idx(0x13) = 7) |
|
40 // 4 - 8 (Iso OUT, Address 0x04, -> EpAddr2Idx(0x04) = 8) |
|
41 // 5 - 11 (Int IN, Address 0x15, -> EpAddr2Idx(0x15) = 11) |
|
42 // |
|
43 // For the reason why this is so (or rather for the perhaps not so obvious system behind it), |
|
44 // see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure |
|
45 // DeviceEndpoints[] at the top of pa_usbc.cpp. |
|
46 |
|
47 // The total number of endpoints in our local endpoint array: |
|
48 static const TInt KUsbTotalEndpoints = 16; //32; // Disabled due to limited FIFO space |
|
49 |
|
50 // The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices): |
|
51 #define IS_VALID_ENDPOINT(x) ((x) > 0 && (x) < KUsbTotalEndpoints) |
|
52 #define IS_OUT_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 0 || (x) == 2 || (x) == 4 || (x) == 6 || (x) == 8 || (x) == 10 || (x) == 12 || (x) == 14 || (x) == 16 || (x) == 18 || (x) == 20 || (x) == 22 ||(x) == 24 || (x) == 26 ||(x) == 28) |
|
53 #define IS_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 1 || (x) == 3 || (x) == 5 || (x) == 7 || (x) == 9 || (x) == 11 || (x) == 13 || (x) == 15 || (x) == 17 || (x) == 19 || (x) == 21 || (x) == 23 ||(x) == 25 || (x) == 27 ||(x) == 29) |
|
54 #define IS_BULK_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 1 || (x) == 3 || (x) == 5 || (x) == 7 || (x) == 9 || (x) == 11 || (x) == 13 || (x) == 15 || (x) == 17 || (x) == 19 || (x) == 21 || (x) == 23 ||(x) == 25 || (x) == 27) |
|
55 #define IS_BULK_OUT_ENDPOINT(x) IS_VALID_ENDPOINT(x) &&((x) == 2 || (x) == 4 || (x) == 6 || (x) == 8 || (x) == 10 || (x) == 12 || (x) == 14 || (x) == 16 || (x) == 18 || (x) == 20 || (x) == 22 ||(x) == 24 || (x) == 26 ||(x) == 28) |
|
56 #define IS_BULK_ENDPOINT(x) (IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x)) |
|
57 #define IS_ISO_IN_ENDPOINT(x) EFalse |
|
58 #define IS_ISO_OUT_ENDPOINT(x) EFalse |
|
59 #define IS_ISO_ENDPOINT(x) (IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x)) |
|
60 #define IS_INT_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 29) |
|
61 |
|
62 // This takes as an index the TTemplateAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11 |
|
63 // and returns the hardware endpoint number 0..5 (note that not all input indices are valid; |
|
64 // these will return -1): |
|
65 /*static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] = |
|
66 {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};*/ |
|
67 static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] = |
|
68 {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; |
|
69 |
|
70 // And here is a function to use the above array: |
|
71 static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint) |
|
72 { |
|
73 if (IS_VALID_ENDPOINT(aRealEndpoint)) return TBeagleAsspEndpoints[aRealEndpoint]; |
|
74 else return -1; |
|
75 } |
|
76 |
|
77 static inline TInt TemplateEp2ArrayIdx(TInt aRealEndpoint) |
|
78 { |
|
79 for(TInt x=0; x<KUsbTotalEndpoints; x++) |
|
80 { |
|
81 if(TBeagleAsspEndpoints[x]==aRealEndpoint) |
|
82 return x; |
|
83 } |
|
84 return -1; |
|
85 } |
|
86 |
|
87 // Access to clocks is reference counted |
|
88 static TInt iSICLKEnabled; |
|
89 |
|
90 // Endpoint max packet sizes |
|
91 static const TInt KEp0MaxPktSz = 64; // Control |
|
92 static const TInt KIntMaxPktSz = 64; // Interrupt |
|
93 static const TInt KBlkMaxPktSz = 512; // Bulk |
|
94 static const TInt KIsoMaxPktSz = 256; // Isochronous |
|
95 static const TInt KEp0MaxPktSzMask = KUsbEpSize64; // Control |
|
96 static const TInt KIntMaxPktSzMask = KUsbEpSize64; // Interrupt |
|
97 static const TInt KBlkMaxPktSzMask = /*KUsbEpSize64 | */KUsbEpSize512; // Bulk |
|
98 static const TInt KIsoMaxPktSzMask = KUsbEpSize256; // Isochronous |
|
99 |
|
100 // 1 ms (i.e. the shortest delay possible with the sort of timer used) seems to give |
|
101 // the best results, both for Bulk and Iso, and also (in the USBRFLCT test program) |
|
102 // both for loop tests as well as unidirectional transfers. |
|
103 static const TInt KRxTimerTimeout = 5; // milliseconds |
|
104 |
|
105 // Used in descriptors |
|
106 static const TUint16 KUsbVendorId = KUsbVendorId_Symbian; // Symbian |
|
107 static const TUint16 KUsbProductId = 0x0666; // bogus... |
|
108 static const TUint16 KUsbDevRelease = 0x0100; // bogus... (BCD!) |
|
109 static const TUint16 KUsbLangId = 0x0409; // English (US) Language ID |
|
110 |
|
111 // String descriptor default values |
|
112 static const wchar_t KStringManufacturer[] = L"Symbian Software Ltd."; |
|
113 static const wchar_t KStringProduct[] = L"BeagleBoard"; |
|
114 static const wchar_t KStringSerialNo[] = L"0123456789"; |
|
115 static const wchar_t KStringConfig[] = L"First and Last and Always"; |
|
116 |
|
117 |
|
118 // We use our own Ep0 state enum: |
|
119 enum TEp0State |
|
120 { |
|
121 EP0_IDLE = 0, // These identifiers don't conform to |
|
122 EP0_OUT_DATA_PHASE = 1, // Symbian's coding standard... ;) |
|
123 EP0_IN_DATA_PHASE = 2, |
|
124 EP0_END_XFER = 3, |
|
125 }; |
|
126 |
|
127 |
|
128 |
|
129 class DOmap3530Usbcc; |
|
130 // The lowest level endpoint abstraction |
|
131 struct TEndpoint |
|
132 { |
|
133 TEndpoint(); |
|
134 static void RxTimerCallback(TAny* aPtr); |
|
135 // data |
|
136 DOmap3530Usbcc* iController; // pointer to controller object |
|
137 union |
|
138 { |
|
139 TUint8* iRxBuf; // where to store / |
|
140 const TUint8* iTxBuf; // from where to send |
|
141 }; |
|
142 union |
|
143 { |
|
144 TInt iReceived; // bytes already rx'ed / |
|
145 TInt iTransmitted; // bytes already tx'ed |
|
146 }; |
|
147 TInt iLength; // number of bytes to be transferred |
|
148 TBool iZlpReqd; // ZeroLengthPacketRequired |
|
149 TBool iNoBuffer; // no data buffer was available when it was needed |
|
150 TBool iDisabled; // dto but stronger |
|
151 TInt iPackets; // number of packets rx'ed or tx'ed |
|
152 TInt iLastError; // |
|
153 TUsbcRequestCallback* iRequest; // |
|
154 NTimer iRxTimer; // |
|
155 TBool iRxTimerSet; // true if iRxTimer is running |
|
156 TBool iRxMoreDataRcvd; // true if after setting timer data have arrived |
|
157 TUsbcPacketArray* iPacketIndex; // actually TUsbcPacketArray (*)[] |
|
158 TUsbcPacketArray* iPacketSize; // actually TUsbcPacketArray (*)[] |
|
159 }; |
|
160 |
|
161 |
|
162 // The hardware driver object proper |
|
163 class Omap3530BoardAssp; |
|
164 class MOmap3530UsbPhy; |
|
165 |
|
166 NONSHARABLE_CLASS( DOmap3530Usbcc ) : public DUsbClientController |
|
167 { |
|
168 friend void TEndpoint::RxTimerCallback(TAny*); |
|
169 |
|
170 public: |
|
171 enum TPHYMode |
|
172 { |
|
173 ENormal, |
|
174 EPowerUp, |
|
175 EPeripheralChirp, |
|
176 EUART |
|
177 }; |
|
178 |
|
179 public: |
|
180 DOmap3530Usbcc(); |
|
181 TInt Construct(); |
|
182 virtual ~DOmap3530Usbcc(); |
|
183 virtual void DumpRegisters(); |
|
184 |
|
185 private: |
|
186 virtual TInt SetDeviceAddress(TInt aAddress); |
|
187 virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo); |
|
188 virtual TInt DeConfigureEndpoint(TInt aRealEndpoint); |
|
189 virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource); |
|
190 virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource); |
|
191 virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const; |
|
192 virtual TInt OpenDmaChannel(TInt aRealEndpoint); |
|
193 virtual void CloseDmaChannel(TInt aRealEndpoint); |
|
194 virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback); |
|
195 virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback); |
|
196 virtual TInt CancelEndpointRead(TInt aRealEndpoint); |
|
197 virtual TInt CancelEndpointWrite(TInt aRealEndpoint); |
|
198 virtual TInt SetupEndpointZeroRead(); |
|
199 virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd = EFalse); |
|
200 virtual TInt SendEp0ZeroByteStatusPacket(); |
|
201 virtual TInt StallEndpoint(TInt aRealEndpoint); |
|
202 virtual TInt ClearStallEndpoint(TInt aRealEndpoint); |
|
203 virtual TInt EndpointStallStatus(TInt aRealEndpoint) const; |
|
204 virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const; |
|
205 virtual TInt ResetDataToggle(TInt aRealEndpoint); |
|
206 virtual TInt SynchFrameNumber() const; |
|
207 virtual void SetSynchFrameNumber(TInt aFrameNumber); |
|
208 virtual TInt StartUdc(); |
|
209 virtual TInt StopUdc(); |
|
210 virtual TInt UdcConnect(); |
|
211 virtual TInt UdcDisconnect(); |
|
212 virtual TBool UsbConnectionStatus() const; |
|
213 virtual TBool UsbPowerStatus() const; |
|
214 virtual TBool DeviceSelfPowered() const; |
|
215 virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const; |
|
216 virtual TInt DeviceTotalEndpoints() const; |
|
217 virtual TBool SoftConnectCaps() const; |
|
218 virtual TBool DeviceStateChangeCaps() const; |
|
219 virtual void Suspend(); |
|
220 virtual void Resume(); |
|
221 virtual void Reset(); |
|
222 virtual TInt SignalRemoteWakeup(); |
|
223 virtual void Ep0ReadSetupPktProceed(); |
|
224 virtual void Ep0ReceiveProceed(); |
|
225 virtual TDfcQue* DfcQ(TInt aUnit); |
|
226 virtual TBool CurrentlyUsingHighSpeed(); |
|
227 |
|
228 private: |
|
229 // general |
|
230 void EnableEndpointInterrupt(TInt aEndpoint); |
|
231 void DisableEndpointInterrupt(TInt aEndpoint); |
|
232 void ClearEndpointInterrupt(TInt aEndpoint); |
|
233 void InitialiseUdcRegisters(); |
|
234 void UdcEnable(); |
|
235 void UdcDisable(); |
|
236 TInt SetupUdcInterrupt(); |
|
237 void ReleaseUdcInterrupt(); |
|
238 void UdcInterruptService(); |
|
239 void EndpointIntService(TInt aEndpoint); |
|
240 TInt ResetIntService(); |
|
241 void SuspendIntService(); |
|
242 void ResumeIntService(); |
|
243 void SofIntService(); |
|
244 static void UdcIsr(TAny* aPtr); |
|
245 static TInt UsbClientConnectorCallback(TAny* aPtr); |
|
246 // endpoint zero |
|
247 void Ep0IntService(); |
|
248 void Ep0ReadSetupPkt(); |
|
249 void Ep0Receive(); |
|
250 void Ep0Transmit(); |
|
251 void Ep0EndXfer(); |
|
252 void Ep0Cancel(); |
|
253 void Ep0PrematureStatusOut(); |
|
254 void Ep0StatusIn(); |
|
255 void Ep0NextState(TEp0State aNextState); |
|
256 // endpoint n with n != 0 |
|
257 void BulkTransmit(TInt aEndpoint); |
|
258 void BulkReceive(TInt aEndpoint); |
|
259 void BulkReadRxFifo(TInt aEndpoint); |
|
260 void IsoTransmit(TInt aEndpoint); |
|
261 void IsoReceive(TInt aEndpoint); |
|
262 void IsoReadRxFifo(TInt aEndpoint); |
|
263 void IntTransmit(TInt aEndpoint); |
|
264 void RxComplete(TEndpoint* aEndpoint); |
|
265 void StopRxTimer(TEndpoint* aEndpoint); |
|
266 |
|
267 private: |
|
268 void EnableSICLK(); |
|
269 void DisableSICLK(); |
|
270 |
|
271 // Dfc functions |
|
272 static void SuspendDfcFn(TAny *aPtr); |
|
273 static void ResumeDfcFn(TAny *aPtr); |
|
274 static void ResetDfcFn(TAny *aPtr); |
|
275 |
|
276 public: |
|
277 TBool DeviceHighSpeedCaps() const; |
|
278 |
|
279 private: |
|
280 // general |
|
281 TBool iSoftwareConnectable; |
|
282 TBool iCableDetectable; |
|
283 TBool iCableConnected; |
|
284 TBool iBusIsPowered; |
|
285 TBool iInitialized; |
|
286 TInt (*iUsbClientConnectorCallback)(TAny *); |
|
287 Omap3530Assp* iAssp; |
|
288 // endpoint zero |
|
289 TBool iEp0Configured; |
|
290 TEp0State iEp0State; |
|
291 // endpoints n |
|
292 TEndpoint iEndpoints[KUsbTotalEndpoints]; // for how this is indexed, see top of pa_usbc.cpp |
|
293 |
|
294 // Dfc's for configuring the Tranceiver when we get a Suspend/Resume/Reset interrupt. |
|
295 TDfcQue* iDfcQueue; |
|
296 |
|
297 TDfc iSuspendDfc; |
|
298 TDfc iResumeDfc; |
|
299 TDfc iResetDfc; |
|
300 |
|
301 MOmap3530UsbPhy* iPhy; |
|
302 TUint iPrmClientId; |
|
303 }; |
|
304 |
|
305 |
|
306 class MOmap3530UsbPhy |
|
307 { |
|
308 public: |
|
309 IMPORT_C static MOmap3530UsbPhy* New(); |
|
310 |
|
311 virtual void StartPHY() = 0; |
|
312 virtual void SetPHYMode( DOmap3530Usbcc::TPHYMode aMode ) = 0; |
|
313 virtual void EnablePHY() = 0; |
|
314 virtual void DisablePHY() = 0; |
|
315 }; |
|
316 |
|
317 |
|
318 #endif // __PA_USBC_H__ |