epoc32/include/assp/omap3530_assp/omap3530_usbc.h
branchSymbian3
changeset 4 837f303aceeb
     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__