1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/assp/omap3530_assp/omap3530_usbc.h Wed Mar 31 12:33:34 2010 +0100
1.3 @@ -0,0 +1,318 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// omap3530/omap3530_drivers/usbcc/omap3530_usbc.h
1.18 +// Platform-dependent USB client controller layer (USB PSL).
1.19 +//
1.20 +
1.21 +
1.22 +#ifndef __OMAP3530_USBC_H__
1.23 +#define __OMAP3530_USBC_H__
1.24 +
1.25 +#include <e32cmn.h>
1.26 +#include <drivers/usbc.h>
1.27 +#include <assp/omap3530_assp/omap3530_assp_priv.h>
1.28 +
1.29 +// This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client
1.30 +// (device) controller.
1.31 +// For simplicity's sake we assume the following endpoint layout of the controller.
1.32 +// We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT),
1.33 +// one Interrupt endpoint (IN), and of course endpoint zero (Ep0).
1.34 +//
1.35 +// This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also
1.36 +// used as the array index for our local TTemplateAsspUsbcc::iEndpoints[]):
1.37 +//
1.38 +// 0 - 0 (Ep0 OUT)
1.39 +// 0 - 1 (Ep0 IN)
1.40 +// 1 - 3 (Bulk IN, Address 0x11, -> EpAddr2Idx(0x11) = 3)
1.41 +// 2 - 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) = 4)
1.42 +// 3 - 7 (Iso IN, Address 0x13, -> EpAddr2Idx(0x13) = 7)
1.43 +// 4 - 8 (Iso OUT, Address 0x04, -> EpAddr2Idx(0x04) = 8)
1.44 +// 5 - 11 (Int IN, Address 0x15, -> EpAddr2Idx(0x15) = 11)
1.45 +//
1.46 +// For the reason why this is so (or rather for the perhaps not so obvious system behind it),
1.47 +// see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure
1.48 +// DeviceEndpoints[] at the top of pa_usbc.cpp.
1.49 +
1.50 +// The total number of endpoints in our local endpoint array:
1.51 +static const TInt KUsbTotalEndpoints = 16; //32; // Disabled due to limited FIFO space
1.52 +
1.53 +// The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices):
1.54 +#define IS_VALID_ENDPOINT(x) ((x) > 0 && (x) < KUsbTotalEndpoints)
1.55 +#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)
1.56 +#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)
1.57 +#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)
1.58 +#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)
1.59 +#define IS_BULK_ENDPOINT(x) (IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x))
1.60 +#define IS_ISO_IN_ENDPOINT(x) EFalse
1.61 +#define IS_ISO_OUT_ENDPOINT(x) EFalse
1.62 +#define IS_ISO_ENDPOINT(x) (IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x))
1.63 +#define IS_INT_IN_ENDPOINT(x) IS_VALID_ENDPOINT(x) && ((x) == 29)
1.64 +
1.65 +// This takes as an index the TTemplateAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11
1.66 +// and returns the hardware endpoint number 0..5 (note that not all input indices are valid;
1.67 +// these will return -1):
1.68 +/*static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] =
1.69 +{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};*/
1.70 +static const TInt TBeagleAsspEndpoints[KUsbTotalEndpoints] =
1.71 +{0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
1.72 +
1.73 +// And here is a function to use the above array:
1.74 +static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint)
1.75 + {
1.76 + if (IS_VALID_ENDPOINT(aRealEndpoint)) return TBeagleAsspEndpoints[aRealEndpoint];
1.77 + else return -1;
1.78 + }
1.79 +
1.80 +static inline TInt TemplateEp2ArrayIdx(TInt aRealEndpoint)
1.81 + {
1.82 + for(TInt x=0; x<KUsbTotalEndpoints; x++)
1.83 + {
1.84 + if(TBeagleAsspEndpoints[x]==aRealEndpoint)
1.85 + return x;
1.86 + }
1.87 + return -1;
1.88 + }
1.89 +
1.90 +// Access to clocks is reference counted
1.91 +static TInt iSICLKEnabled;
1.92 +
1.93 +// Endpoint max packet sizes
1.94 +static const TInt KEp0MaxPktSz = 64; // Control
1.95 +static const TInt KIntMaxPktSz = 64; // Interrupt
1.96 +static const TInt KBlkMaxPktSz = 512; // Bulk
1.97 +static const TInt KIsoMaxPktSz = 256; // Isochronous
1.98 +static const TInt KEp0MaxPktSzMask = KUsbEpSize64; // Control
1.99 +static const TInt KIntMaxPktSzMask = KUsbEpSize64; // Interrupt
1.100 +static const TInt KBlkMaxPktSzMask = /*KUsbEpSize64 | */KUsbEpSize512; // Bulk
1.101 +static const TInt KIsoMaxPktSzMask = KUsbEpSize256; // Isochronous
1.102 +
1.103 +// 1 ms (i.e. the shortest delay possible with the sort of timer used) seems to give
1.104 +// the best results, both for Bulk and Iso, and also (in the USBRFLCT test program)
1.105 +// both for loop tests as well as unidirectional transfers.
1.106 +static const TInt KRxTimerTimeout = 5; // milliseconds
1.107 +
1.108 +// Used in descriptors
1.109 +static const TUint16 KUsbVendorId = KUsbVendorId_Symbian; // Symbian
1.110 +static const TUint16 KUsbProductId = 0x0666; // bogus...
1.111 +static const TUint16 KUsbDevRelease = 0x0100; // bogus... (BCD!)
1.112 +static const TUint16 KUsbLangId = 0x0409; // English (US) Language ID
1.113 +
1.114 +// String descriptor default values
1.115 +static const wchar_t KStringManufacturer[] = L"Symbian Software Ltd.";
1.116 +static const wchar_t KStringProduct[] = L"BeagleBoard";
1.117 +static const wchar_t KStringSerialNo[] = L"0123456789";
1.118 +static const wchar_t KStringConfig[] = L"First and Last and Always";
1.119 +
1.120 +
1.121 +// We use our own Ep0 state enum:
1.122 +enum TEp0State
1.123 + {
1.124 + EP0_IDLE = 0, // These identifiers don't conform to
1.125 + EP0_OUT_DATA_PHASE = 1, // Symbian's coding standard... ;)
1.126 + EP0_IN_DATA_PHASE = 2,
1.127 + EP0_END_XFER = 3,
1.128 + };
1.129 +
1.130 +
1.131 +
1.132 +class DOmap3530Usbcc;
1.133 +// The lowest level endpoint abstraction
1.134 +struct TEndpoint
1.135 + {
1.136 + TEndpoint();
1.137 + static void RxTimerCallback(TAny* aPtr);
1.138 + // data
1.139 + DOmap3530Usbcc* iController; // pointer to controller object
1.140 + union
1.141 + {
1.142 + TUint8* iRxBuf; // where to store /
1.143 + const TUint8* iTxBuf; // from where to send
1.144 + };
1.145 + union
1.146 + {
1.147 + TInt iReceived; // bytes already rx'ed /
1.148 + TInt iTransmitted; // bytes already tx'ed
1.149 + };
1.150 + TInt iLength; // number of bytes to be transferred
1.151 + TBool iZlpReqd; // ZeroLengthPacketRequired
1.152 + TBool iNoBuffer; // no data buffer was available when it was needed
1.153 + TBool iDisabled; // dto but stronger
1.154 + TInt iPackets; // number of packets rx'ed or tx'ed
1.155 + TInt iLastError; //
1.156 + TUsbcRequestCallback* iRequest; //
1.157 + NTimer iRxTimer; //
1.158 + TBool iRxTimerSet; // true if iRxTimer is running
1.159 + TBool iRxMoreDataRcvd; // true if after setting timer data have arrived
1.160 + TUsbcPacketArray* iPacketIndex; // actually TUsbcPacketArray (*)[]
1.161 + TUsbcPacketArray* iPacketSize; // actually TUsbcPacketArray (*)[]
1.162 + };
1.163 +
1.164 +
1.165 +// The hardware driver object proper
1.166 +class Omap3530BoardAssp;
1.167 +class MOmap3530UsbPhy;
1.168 +
1.169 +NONSHARABLE_CLASS( DOmap3530Usbcc ) : public DUsbClientController
1.170 + {
1.171 +friend void TEndpoint::RxTimerCallback(TAny*);
1.172 +
1.173 +public:
1.174 + enum TPHYMode
1.175 + {
1.176 + ENormal,
1.177 + EPowerUp,
1.178 + EPeripheralChirp,
1.179 + EUART
1.180 + };
1.181 +
1.182 +public:
1.183 + DOmap3530Usbcc();
1.184 + TInt Construct();
1.185 + virtual ~DOmap3530Usbcc();
1.186 + virtual void DumpRegisters();
1.187 +
1.188 +private:
1.189 + virtual TInt SetDeviceAddress(TInt aAddress);
1.190 + virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo);
1.191 + virtual TInt DeConfigureEndpoint(TInt aRealEndpoint);
1.192 + virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
1.193 + virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource);
1.194 + virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const;
1.195 + virtual TInt OpenDmaChannel(TInt aRealEndpoint);
1.196 + virtual void CloseDmaChannel(TInt aRealEndpoint);
1.197 + virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
1.198 + virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback);
1.199 + virtual TInt CancelEndpointRead(TInt aRealEndpoint);
1.200 + virtual TInt CancelEndpointWrite(TInt aRealEndpoint);
1.201 + virtual TInt SetupEndpointZeroRead();
1.202 + virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd = EFalse);
1.203 + virtual TInt SendEp0ZeroByteStatusPacket();
1.204 + virtual TInt StallEndpoint(TInt aRealEndpoint);
1.205 + virtual TInt ClearStallEndpoint(TInt aRealEndpoint);
1.206 + virtual TInt EndpointStallStatus(TInt aRealEndpoint) const;
1.207 + virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const;
1.208 + virtual TInt ResetDataToggle(TInt aRealEndpoint);
1.209 + virtual TInt SynchFrameNumber() const;
1.210 + virtual void SetSynchFrameNumber(TInt aFrameNumber);
1.211 + virtual TInt StartUdc();
1.212 + virtual TInt StopUdc();
1.213 + virtual TInt UdcConnect();
1.214 + virtual TInt UdcDisconnect();
1.215 + virtual TBool UsbConnectionStatus() const;
1.216 + virtual TBool UsbPowerStatus() const;
1.217 + virtual TBool DeviceSelfPowered() const;
1.218 + virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const;
1.219 + virtual TInt DeviceTotalEndpoints() const;
1.220 + virtual TBool SoftConnectCaps() const;
1.221 + virtual TBool DeviceStateChangeCaps() const;
1.222 + virtual void Suspend();
1.223 + virtual void Resume();
1.224 + virtual void Reset();
1.225 + virtual TInt SignalRemoteWakeup();
1.226 + virtual void Ep0ReadSetupPktProceed();
1.227 + virtual void Ep0ReceiveProceed();
1.228 + virtual TDfcQue* DfcQ(TInt aUnit);
1.229 + virtual TBool CurrentlyUsingHighSpeed();
1.230 +
1.231 +private:
1.232 + // general
1.233 + void EnableEndpointInterrupt(TInt aEndpoint);
1.234 + void DisableEndpointInterrupt(TInt aEndpoint);
1.235 + void ClearEndpointInterrupt(TInt aEndpoint);
1.236 + void InitialiseUdcRegisters();
1.237 + void UdcEnable();
1.238 + void UdcDisable();
1.239 + TInt SetupUdcInterrupt();
1.240 + void ReleaseUdcInterrupt();
1.241 + void UdcInterruptService();
1.242 + void EndpointIntService(TInt aEndpoint);
1.243 + TInt ResetIntService();
1.244 + void SuspendIntService();
1.245 + void ResumeIntService();
1.246 + void SofIntService();
1.247 + static void UdcIsr(TAny* aPtr);
1.248 + static TInt UsbClientConnectorCallback(TAny* aPtr);
1.249 + // endpoint zero
1.250 + void Ep0IntService();
1.251 + void Ep0ReadSetupPkt();
1.252 + void Ep0Receive();
1.253 + void Ep0Transmit();
1.254 + void Ep0EndXfer();
1.255 + void Ep0Cancel();
1.256 + void Ep0PrematureStatusOut();
1.257 + void Ep0StatusIn();
1.258 + void Ep0NextState(TEp0State aNextState);
1.259 + // endpoint n with n != 0
1.260 + void BulkTransmit(TInt aEndpoint);
1.261 + void BulkReceive(TInt aEndpoint);
1.262 + void BulkReadRxFifo(TInt aEndpoint);
1.263 + void IsoTransmit(TInt aEndpoint);
1.264 + void IsoReceive(TInt aEndpoint);
1.265 + void IsoReadRxFifo(TInt aEndpoint);
1.266 + void IntTransmit(TInt aEndpoint);
1.267 + void RxComplete(TEndpoint* aEndpoint);
1.268 + void StopRxTimer(TEndpoint* aEndpoint);
1.269 +
1.270 +private:
1.271 + void EnableSICLK();
1.272 + void DisableSICLK();
1.273 +
1.274 + // Dfc functions
1.275 + static void SuspendDfcFn(TAny *aPtr);
1.276 + static void ResumeDfcFn(TAny *aPtr);
1.277 + static void ResetDfcFn(TAny *aPtr);
1.278 +
1.279 +public:
1.280 + TBool DeviceHighSpeedCaps() const;
1.281 +
1.282 +private:
1.283 + // general
1.284 + TBool iSoftwareConnectable;
1.285 + TBool iCableDetectable;
1.286 + TBool iCableConnected;
1.287 + TBool iBusIsPowered;
1.288 + TBool iInitialized;
1.289 + TInt (*iUsbClientConnectorCallback)(TAny *);
1.290 + Omap3530Assp* iAssp;
1.291 + // endpoint zero
1.292 + TBool iEp0Configured;
1.293 + TEp0State iEp0State;
1.294 + // endpoints n
1.295 + TEndpoint iEndpoints[KUsbTotalEndpoints]; // for how this is indexed, see top of pa_usbc.cpp
1.296 +
1.297 + // Dfc's for configuring the Tranceiver when we get a Suspend/Resume/Reset interrupt.
1.298 + TDfcQue* iDfcQueue;
1.299 +
1.300 + TDfc iSuspendDfc;
1.301 + TDfc iResumeDfc;
1.302 + TDfc iResetDfc;
1.303 +
1.304 + MOmap3530UsbPhy* iPhy;
1.305 + TUint iPrmClientId;
1.306 + };
1.307 +
1.308 +
1.309 +class MOmap3530UsbPhy
1.310 + {
1.311 +public:
1.312 + IMPORT_C static MOmap3530UsbPhy* New();
1.313 +
1.314 + virtual void StartPHY() = 0;
1.315 + virtual void SetPHYMode( DOmap3530Usbcc::TPHYMode aMode ) = 0;
1.316 + virtual void EnablePHY() = 0;
1.317 + virtual void DisablePHY() = 0;
1.318 + };
1.319 +
1.320 +
1.321 +#endif // __PA_USBC_H__