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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // omap3530/omap3530_drivers/usbcc/omap3530_usbc.h
15 // Platform-dependent USB client controller layer (USB PSL).
19 #ifndef __OMAP3530_USBC_H__
20 #define __OMAP3530_USBC_H__
23 #include <drivers/usbc.h>
24 #include <assp/omap3530_assp/omap3530_assp_priv.h>
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).
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[]):
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)
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.
47 // The total number of endpoints in our local endpoint array:
48 static const TInt KUsbTotalEndpoints = 16; //32; // Disabled due to limited FIFO space
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)
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};
70 // And here is a function to use the above array:
71 static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint)
73 if (IS_VALID_ENDPOINT(aRealEndpoint)) return TBeagleAsspEndpoints[aRealEndpoint];
77 static inline TInt TemplateEp2ArrayIdx(TInt aRealEndpoint)
79 for(TInt x=0; x<KUsbTotalEndpoints; x++)
81 if(TBeagleAsspEndpoints[x]==aRealEndpoint)
87 // Access to clocks is reference counted
88 static TInt iSICLKEnabled;
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
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
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
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";
118 // We use our own Ep0 state enum:
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,
129 class DOmap3530Usbcc;
130 // The lowest level endpoint abstraction
134 static void RxTimerCallback(TAny* aPtr);
136 DOmap3530Usbcc* iController; // pointer to controller object
139 TUint8* iRxBuf; // where to store /
140 const TUint8* iTxBuf; // from where to send
144 TInt iReceived; // bytes already rx'ed /
145 TInt iTransmitted; // bytes already tx'ed
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
153 TUsbcRequestCallback* iRequest; //
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 (*)[]
162 // The hardware driver object proper
163 class Omap3530BoardAssp;
164 class MOmap3530UsbPhy;
166 NONSHARABLE_CLASS( DOmap3530Usbcc ) : public DUsbClientController
168 friend void TEndpoint::RxTimerCallback(TAny*);
182 virtual ~DOmap3530Usbcc();
183 virtual void DumpRegisters();
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();
230 void EnableEndpointInterrupt(TInt aEndpoint);
231 void DisableEndpointInterrupt(TInt aEndpoint);
232 void ClearEndpointInterrupt(TInt aEndpoint);
233 void InitialiseUdcRegisters();
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);
247 void Ep0IntService();
248 void Ep0ReadSetupPkt();
253 void Ep0PrematureStatusOut();
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);
272 static void SuspendDfcFn(TAny *aPtr);
273 static void ResumeDfcFn(TAny *aPtr);
274 static void ResetDfcFn(TAny *aPtr);
277 TBool DeviceHighSpeedCaps() const;
281 TBool iSoftwareConnectable;
282 TBool iCableDetectable;
283 TBool iCableConnected;
286 TInt (*iUsbClientConnectorCallback)(TAny *);
289 TBool iEp0Configured;
292 TEndpoint iEndpoints[KUsbTotalEndpoints]; // for how this is indexed, see top of pa_usbc.cpp
294 // Dfc's for configuring the Tranceiver when we get a Suspend/Resume/Reset interrupt.
301 MOmap3530UsbPhy* iPhy;
306 class MOmap3530UsbPhy
309 IMPORT_C static MOmap3530UsbPhy* New();
311 virtual void StartPHY() = 0;
312 virtual void SetPHYMode( DOmap3530Usbcc::TPHYMode aMode ) = 0;
313 virtual void EnablePHY() = 0;
314 virtual void DisablePHY() = 0;
318 #endif // __PA_USBC_H__