sl@0: // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\include\drivers\usbcshared.h sl@0: // Kernel side definitions for the USB Device driver stack (PIL + LDD). sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file usbcshared.h sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #ifndef __USBCSHARED_H__ sl@0: #define __USBCSHARED_H__ sl@0: sl@0: #include sl@0: sl@0: // Define here what options are required: sl@0: // (USB_SUPPORTS_CONTROLENDPOINTS and USB_SUPPORTS_SET_DESCRIPTOR_REQUEST sl@0: // have never been tested though...) sl@0: //#define USB_SUPPORTS_CONTROLENDPOINTS sl@0: //#define USB_SUPPORTS_SET_DESCRIPTOR_REQUEST sl@0: sl@0: #include sl@0: sl@0: // Debug Support sl@0: sl@0: // Use for debugging purposes only (commented out for normal operation): sl@0: //#define USBC_LDD_BUFFER_TRACE sl@0: sl@0: static const char KUsbPILPanicCat[] = "USB PIL FAULT"; // kernel fault category sl@0: _LIT(KUsbPILKillCat, "USB PIL KILL"); // thread kill category sl@0: _LIT(KUsbLDDKillCat, "USB LDD KILL"); // thread kill category sl@0: sl@0: /** Error code for stalled endpoint. sl@0: */ sl@0: const TInt KErrEndpointStall = KErrLocked; sl@0: sl@0: /** Error code for Ep0 write prematurely ended by a host OUT token. sl@0: */ sl@0: const TInt KErrPrematureEnd = KErrDiskFull; sl@0: sl@0: /** The following constants control the buffer arrangement for OUT transfers (IN transfers have only 1 sl@0: buffer). The total size of buffering for an OUT endpoint will be number of buffers * buffersize, sl@0: so that, for example, a Bulk OUT endpoint will have KUsbcDmaBufNumBulk * KUsbcDmaBufSzBulk bytes of sl@0: buffering. sl@0: These buffers will be physically contiguous, so that DMA may be used. sl@0: The number of buffers MUST be >=2 - otherwise the buffering scheme won't work. sl@0: The buffer sizes should be an exact fraction of 4kB and the number of buffers such that the sl@0: buffersize * number of buffers is an exact multiple of 4kB, otherwise memory will be wasted. sl@0: */ sl@0: /** Size of a Control ep buffer. sl@0: */ sl@0: const TInt KUsbcDmaBufSzControl = 1024; sl@0: sl@0: /** Size of a Bulk ep buffer. sl@0: */ sl@0: const TInt KUsbcDmaBufSzBulk = 4096; sl@0: sl@0: /** Size of an Interrupt ep buffer. sl@0: */ sl@0: const TInt KUsbcDmaBufSzInterrupt = 4096; sl@0: sl@0: /** Size of an Isochronous ep buffer. sl@0: */ sl@0: const TInt KUsbcDmaBufSzIsochronous = 4096; sl@0: sl@0: /** Number of buffers for Control OUT endpoints. sl@0: */ sl@0: const TInt KUsbcDmaBufNumControl = 2; sl@0: sl@0: /** Number of buffers for Isochronous OUT endpoints. sl@0: */ sl@0: const TInt KUsbcDmaBufNumIsochronous = 2; sl@0: sl@0: /** Number of buffers for Bulk OUT endpoints. sl@0: */ sl@0: const TInt KUsbcDmaBufNumBulk = 2; sl@0: sl@0: /** Number of buffers for Interrupt OUT endpoints. sl@0: */ sl@0: const TInt KUsbcDmaBufNumInterrupt = 2; sl@0: sl@0: /** Maximum buffer number. sl@0: */ sl@0: const TInt KUsbcDmaBufNumMax = MAX4(KUsbcDmaBufNumControl, KUsbcDmaBufNumIsochronous, sl@0: KUsbcDmaBufNumBulk, KUsbcDmaBufNumInterrupt); sl@0: sl@0: /** Maximum number of recorded packets possible. sl@0: */ sl@0: const TUint KUsbcDmaBufMaxPkts = 2; sl@0: sl@0: /** Number of arrays. sl@0: */ sl@0: const TInt KUsbcDmaBufNumArrays = 2; sl@0: sl@0: /** Max size that Ep0 packets might have. sl@0: */ sl@0: const TInt KUsbcBufSzControl = 64; sl@0: sl@0: /** The Ep0 RX data collection buffer area. sl@0: (Arbitrary size, judged to be sufficient for SET_DESCRIPTOR requests) sl@0: */ sl@0: const TInt KUsbcBufSz_Ep0Rx = 1024; sl@0: sl@0: /** The Ep0 TX buffer area. sl@0: (Size sufficient to hold as much data as can be requested via GET_DESCRIPTOR) sl@0: */ sl@0: const TInt KUsbcBufSz_Ep0Tx = 1024 * 64; sl@0: sl@0: sl@0: /** The USB version the stack is compliant with: 2.0 (BCD). sl@0: */ sl@0: const TUint16 KUsbcUsbVersion = 0x0200; sl@0: sl@0: /** Maximum number of endpoints an interface (i.e. LDD) may have. sl@0: */ sl@0: const TInt KUsbcMaxEpNumber = 5; sl@0: sl@0: /** Status FIFO depth; enough for 2 complete configs. sl@0: */ sl@0: const TInt KUsbDeviceStatusQueueDepth = 15; sl@0: sl@0: /** = 'no status info'. sl@0: */ sl@0: const TUint32 KUsbDeviceStatusNull = 0xffffffffu; sl@0: sl@0: /** = 'no buffer available'. sl@0: */ sl@0: const TInt KUsbcInvalidBufferIndex = -1; sl@0: sl@0: /** = 'no packet available'. sl@0: */ sl@0: const TUint KUsbcInvalidPacketIndex = (TUint)(-1); sl@0: sl@0: /** = 'no drainable buffers'. sl@0: */ sl@0: const TInt KUsbcInvalidDrainQueueIndex = -1; sl@0: sl@0: /** Number of possible bandwidth priorities. sl@0: */ sl@0: const TInt KUsbcDmaBufMaxPriorities = 4; sl@0: sl@0: // The following buffer sizes are used within the LDD for the different sl@0: // user-selectable endpoint bandwidth priorities sl@0: // (EUsbcBandwidthOUTDefault/Plus1/Plus2/Maximum + the same for 'IN'). sl@0: // These values, in particular those for the Maximum setting, were obtained sl@0: // empirically. sl@0: sl@0: /** Bulk IN buffer sizes for different priorities (4K, 16K, 64K, 512K). sl@0: */ sl@0: const TInt KUsbcDmaBufSizesBulkIN[KUsbcDmaBufMaxPriorities] = sl@0: {KUsbcDmaBufSzBulk, 0x4000, 0x10000, 0x80000}; sl@0: sl@0: /** Bulk OUT buffer sizes for different priorities (4K, 16K, 64K, 512K). sl@0: */ sl@0: const TInt KUsbcDmaBufSizesBulkOUT[KUsbcDmaBufMaxPriorities] = sl@0: {KUsbcDmaBufSzBulk, 0x4000, 0x10000, 0x80000}; sl@0: sl@0: /** Number of UDCs supported in the system. sl@0: (Support for more than one UDC is preliminary.) sl@0: */ sl@0: const TInt KUsbcMaxUdcs = 2; sl@0: sl@0: /** Number of endpoints a USB device can have. sl@0: (30 regular endpoints + 2 x Ep0) sl@0: */ sl@0: const TInt KUsbcEpArraySize = KUsbcMaxEndpoints + 2; sl@0: sl@0: /** Number of notification requests of the same kind that can be registered at sl@0: a time. As normally not more than one request per kind per LDD is sl@0: permitted, this number is roughly equivalent to the maximum number of LDDs sl@0: that can be operating at the same time. sl@0: This constant is used by the PIL while maintaining its request lists sl@0: (iClientCallbacks, iStatusCallbacks, iEpStatusCallbacks, iOtgCallbacks) to sl@0: ensure that the lists are of a finite length and thus the list traverse sl@0: time is bounded. sl@0: This value is chosen with the maximum number of USB interfaces (not sl@0: settings) allowed by the spec for a single device in mind. sl@0: */ sl@0: const TInt KUsbcMaxListLength = 256; sl@0: sl@0: /** Used by the LDD. sl@0: */ sl@0: typedef TUint32 TUsbcPacketArray; sl@0: sl@0: sl@0: /** Used as a return value from DUsbClientController::EnquireEp0NextState(), sl@0: the purpose of which is to enable the PSL to find out what the next stage sl@0: will be for a newly received Setup packet. sl@0: sl@0: The enum values are self-explanatory. sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: enum TUsbcEp0State sl@0: { sl@0: EEp0StateDataIn, sl@0: EEp0StateDataOut, sl@0: EEp0StateStatusIn sl@0: }; sl@0: sl@0: sl@0: /** Used to show the direction of a transfer request to the Controller. sl@0: sl@0: @see TUsbcRequestCallback sl@0: */ sl@0: enum TTransferDirection {EControllerNone, EControllerRead, EControllerWrite}; sl@0: sl@0: sl@0: /** These event codes are used by the PSL to tell the PIL what has happened. sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: enum TUsbcDeviceEvent sl@0: { sl@0: /** The USB Suspend bus state has been detected. */ sl@0: EUsbEventSuspend, sl@0: /** USB Resume signalling has been detected. */ sl@0: EUsbEventResume, sl@0: /** A USB Reset condition has been detected. */ sl@0: EUsbEventReset, sl@0: /** Physical removal of the USB cable has been detected. */ sl@0: EUsbEventCableRemoved, sl@0: /** Physical insertion of the USB cable has been detected. */ sl@0: EUsbEventCableInserted sl@0: }; sl@0: sl@0: sl@0: /** USB LDD client callback. sl@0: */ sl@0: class TUsbcClientCallback sl@0: { sl@0: public: sl@0: inline TUsbcClientCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority); sl@0: inline DBase* Owner() const; sl@0: inline TInt DoCallback(); sl@0: inline void Cancel(); sl@0: inline void SetDfcQ(TDfcQue* aDfcQ); sl@0: public: sl@0: /** Used by the PIL to queue callback objects into a TSglQue. */ sl@0: TSglQueLink iLink; sl@0: private: sl@0: DBase* iOwner; sl@0: TDfc iDfc; sl@0: }; sl@0: sl@0: sl@0: /** The endpoint halt/clear_halt status. sl@0: */ sl@0: class TUsbcEndpointStatusCallback sl@0: { sl@0: public: sl@0: inline TUsbcEndpointStatusCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority); sl@0: inline void SetState(TUint aState); sl@0: inline TUint State() const; sl@0: inline DBase* Owner() const; sl@0: inline TInt DoCallback(); sl@0: inline void Cancel(); sl@0: inline void SetDfcQ(TDfcQue* aDfcQ); sl@0: public: sl@0: /** Used by the PIL to queue callback objects into a TSglQue. */ sl@0: TSglQueLink iLink; sl@0: private: sl@0: DBase* iOwner; sl@0: TDfc iDfc; sl@0: TUint iState; sl@0: }; sl@0: sl@0: sl@0: /** Maximum number of device status requests that can be queued at a time. sl@0: The value chosen is thought to be sufficient in all situations. sl@0: */ sl@0: const TInt KUsbcDeviceStateRequests = 8; sl@0: sl@0: sl@0: /** The USB device status. sl@0: */ sl@0: class TUsbcStatusCallback sl@0: { sl@0: public: sl@0: inline TUsbcStatusCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority); sl@0: inline void SetState(TUsbcDeviceState aState); sl@0: inline TUsbcDeviceState State(TInt aIndex) const; sl@0: inline void ResetState(); sl@0: inline DBase* Owner() const; sl@0: inline TInt DoCallback(); sl@0: inline void Cancel(); sl@0: inline void SetDfcQ(TDfcQue* aDfcQ); sl@0: public: sl@0: /** Used by the PIL to queue callback objects into a TSglQue. */ sl@0: TSglQueLink iLink; sl@0: private: sl@0: DBase* iOwner; sl@0: TDfc iDfc; sl@0: TUsbcDeviceState iState[KUsbcDeviceStateRequests]; sl@0: }; sl@0: sl@0: sl@0: /** A USB transfer request. sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class TUsbcRequestCallback sl@0: { sl@0: public: sl@0: /** @internalTechnology */ sl@0: inline TUsbcRequestCallback(const DBase* aOwner, TInt aEndpointNum, TDfcFn aDfcFunc, sl@0: TAny* aEndpoint, TDfcQue* aDfcQ, TInt aPriority); sl@0: /** @internalTechnology */ sl@0: inline ~TUsbcRequestCallback(); sl@0: /** @internalTechnology */ sl@0: inline void SetRxBufferInfo(TUint8* aBufferStart, TPhysAddr aBufferAddr, sl@0: TUsbcPacketArray* aPacketIndex, TUsbcPacketArray* aPacketSize, sl@0: TInt aLength); sl@0: /** @internalTechnology */ sl@0: inline void SetTxBufferInfo(TUint8* aBufferStart, TPhysAddr aBufferAddr, TInt aLength); sl@0: /** @internalTechnology */ sl@0: inline void SetTransferDirection(TTransferDirection aTransferDir); sl@0: /** @internalTechnology */ sl@0: inline const DBase* Owner() const; sl@0: /** @internalTechnology */ sl@0: inline TInt DoCallback(); sl@0: /** @internalTechnology */ sl@0: inline void Cancel(); sl@0: public: sl@0: /** Used by the PIL to queue callback objects into a TSglQue. sl@0: @internalTechnology sl@0: */ sl@0: TSglQueLink iLink; sl@0: public: sl@0: /** The endpoint number. */ sl@0: const TInt iEndpointNum; sl@0: /** The 'real' endpoint number, as used by the PDD. */ sl@0: TInt iRealEpNum; sl@0: /** Indicates the LDD client for this transfer. */ sl@0: const DBase* const iOwner; sl@0: /** DFC, used by PIL to call back the LDD when transfer completes to the LDD. */ sl@0: TDfc iDfc; sl@0: /** Direction of transfer request. */ sl@0: TTransferDirection iTransferDir; sl@0: /** Start address of this buffer. */ sl@0: TUint8* iBufferStart; sl@0: /** Physical address of buffer start (used for DMA). */ sl@0: TPhysAddr iBufferAddr; sl@0: /** Array of pointers into iBufferStart (actually TUsbcPacketArray (*)[]). */ sl@0: TUsbcPacketArray* iPacketIndex; sl@0: /** Array of packet sizes (actually TUsbcPacketArray (*)[]). */ sl@0: TUsbcPacketArray* iPacketSize; sl@0: /** Length in bytes of buffer (iBufferStart). */ sl@0: TInt iLength; sl@0: /** For IN transfers, if a zlp might be required at the end of this transfer. */ sl@0: TBool iZlpReqd; sl@0: /** Number of bytes transmitted; changed by the PSL. */ sl@0: TUint iTxBytes; sl@0: /** Number of packets received (if it is a read); changed by the PSL. */ sl@0: TUint iRxPackets; sl@0: /** The error code upon completion of the request; changed by the PSL. */ sl@0: TInt iError; sl@0: }; sl@0: sl@0: /** USB On-The-Go feature change callback. sl@0: */ sl@0: class TUsbcOtgFeatureCallback sl@0: { sl@0: public: sl@0: inline TUsbcOtgFeatureCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority); sl@0: inline void SetFeatures(TUint8 aFeatures); sl@0: inline TUint8 Features() const; sl@0: inline DBase* Owner() const; sl@0: inline TInt DoCallback(); sl@0: inline void Cancel(); sl@0: inline void SetDfcQ(TDfcQue* aDfcQ); sl@0: public: sl@0: /** Used by the PIL to queue callback objects into a TSglQue. */ sl@0: TSglQueLink iLink; sl@0: private: sl@0: DBase* iOwner; sl@0: TDfc iDfc; sl@0: TUint8 iValue; sl@0: }; sl@0: sl@0: // sl@0: //########################### Physical Device Driver (PIL + PSL) ###################### sl@0: // sl@0: sl@0: class TUsbcLogicalEndpoint; sl@0: sl@0: /** This models a physical (real) endpoint of the UDC. sl@0: */ sl@0: class TUsbcPhysicalEndpoint sl@0: { sl@0: public: sl@0: TUsbcPhysicalEndpoint(); sl@0: ~TUsbcPhysicalEndpoint(); sl@0: TBool EndpointSuitable(const TUsbcEndpointInfo* aEpInfo, TInt aIfcNumber) const; // Check Todo, SC will pass pointer to derived class sl@0: TInt TypeAvailable(TUint aType) const; sl@0: TInt DirAvailable(TUint aDir) const; sl@0: public: sl@0: /** This endpoint's capabilities. */ sl@0: TUsbcEndpointCaps iCaps; sl@0: /** USB address: 0x00, 0x80, 0x01, 0x81, etc. */ sl@0: TUint8 iEndpointAddr; sl@0: /** Pointer to interface # this endpoint has been assigned to. */ sl@0: const TUint8* iIfcNumber; sl@0: /** Pointer to corresponding logical endpoint or NULL. */ sl@0: const TUsbcLogicalEndpoint* iLEndpoint; sl@0: /** Only used when searching for available endpoints. */ sl@0: TBool iSettingReserve; sl@0: /** True if endpoint is halted (i.e. issues STALL handshakes), false otherwise. */ sl@0: TBool iHalt; sl@0: }; sl@0: sl@0: sl@0: class DUsbClientController; sl@0: class TUsbcInterface; sl@0: sl@0: /** This is a 'logical' endpoint, as used by our device configuration model. sl@0: */ sl@0: class TUsbcLogicalEndpoint sl@0: { sl@0: public: sl@0: TUsbcLogicalEndpoint(DUsbClientController* aController, TUint aEndpointNum, sl@0: const TUsbcEndpointInfo& aEpInfo, TUsbcInterface* aInterface, sl@0: TUsbcPhysicalEndpoint* aPEndpoint); // Check Todo, SC will pass pointer to derived class sl@0: ~TUsbcLogicalEndpoint(); sl@0: public: sl@0: /** Pointer to controller object. */ sl@0: DUsbClientController* iController; sl@0: /** The virtual (logical) endpoint number. */ sl@0: const TInt iLEndpointNum; sl@0: /** This endpoint's info structure. */ sl@0: TUsbcEndpointInfo iInfo; // Check Todo, SC will pass pointer to derived class sl@0: /** Stores the endpoint size to be used for FS. */ sl@0: TInt iEpSize_Fs; sl@0: /** Stores the endpoint size to be used for HS. */ sl@0: TInt iEpSize_Hs; sl@0: /** 'Back' pointer. */ sl@0: const TUsbcInterface* iInterface; sl@0: /** Pointer to corresponding physical endpoint, never NULL. */ sl@0: TUsbcPhysicalEndpoint* const iPEndpoint; sl@0: }; sl@0: sl@0: sl@0: class TUsbcInterfaceSet; sl@0: sl@0: /** This is an 'alternate setting' of an interface. sl@0: */ sl@0: class TUsbcInterface sl@0: { sl@0: public: sl@0: TUsbcInterface(TUsbcInterfaceSet* aIfcSet, TUint8 aSetting, TBool aNoEp0Requests); sl@0: ~TUsbcInterface(); sl@0: public: sl@0: /** Array of endpoints making up (belonging to) this setting. */ sl@0: RPointerArray iEndpoints; sl@0: /** 'Back' pointer. */ sl@0: TUsbcInterfaceSet* const iInterfaceSet; sl@0: /** bAlternateSetting (zero-based). */ sl@0: const TUint8 iSettingCode; sl@0: /** KUsbcInterfaceInfo_NoEp0RequestsPlease: stall non-std Setup requests. */ sl@0: const TBool iNoEp0Requests; sl@0: }; sl@0: sl@0: sl@0: /** This is an 'interface' (owning 1 or more alternate settings). sl@0: sl@0: @see TUsbcInterface sl@0: */ sl@0: class TUsbcInterfaceSet sl@0: { sl@0: public: sl@0: TUsbcInterfaceSet(const DBase* aClientId, TUint8 aIfcNum); sl@0: ~TUsbcInterfaceSet(); sl@0: inline const TUsbcInterface* CurrentInterface() const; sl@0: inline TUsbcInterface* CurrentInterface(); sl@0: public: sl@0: /** Array of alternate settings provided by (belonging to) this interface. */ sl@0: RPointerArray iInterfaces; sl@0: /** Pointer to the LDD which created and owns this interface. */ sl@0: const DBase* const iClientId; sl@0: /** bInterfaceNumber (zero-based). */ sl@0: TUint8 iInterfaceNumber; sl@0: /** bAlternateSetting (zero-based). */ sl@0: TUint8 iCurrentInterface; sl@0: }; sl@0: sl@0: sl@0: /** This is a 'configuration' of the USB device. sl@0: Currently we support only one configuration. sl@0: */ sl@0: class TUsbcConfiguration sl@0: { sl@0: public: sl@0: TUsbcConfiguration(TUint8 aConfigVal); sl@0: ~TUsbcConfiguration(); sl@0: public: sl@0: /** Array of interfaces making up (belonging to) this configuration. */ sl@0: RPointerArray iInterfaceSets; sl@0: /** bConfigurationValue (one-based). */ sl@0: const TUint8 iConfigValue; sl@0: }; sl@0: sl@0: sl@0: /** A USB Setup packet. sl@0: sl@0: Used mainly internally by the PIL but also by sl@0: DUsbClientController::ProcessSetConfiguration(const TUsbcSetup&), sl@0: which is classified as publishedPartner. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: struct TUsbcSetup sl@0: { sl@0: /** bmRequestType */ sl@0: TUint8 iRequestType; sl@0: /** bRequest */ sl@0: TUint8 iRequest; sl@0: /** wValue */ sl@0: TUint16 iValue; sl@0: /** wIndex */ sl@0: TUint16 iIndex; sl@0: /** wLength */ sl@0: TUint16 iLength; sl@0: }; sl@0: sl@0: sl@0: /** The USB controller's power handler class. sl@0: */ sl@0: class DUsbcPowerHandler : public DPowerHandler sl@0: { sl@0: public: sl@0: void PowerUp(); sl@0: void PowerDown(TPowerState); sl@0: public: sl@0: DUsbcPowerHandler(DUsbClientController* aController); sl@0: private: sl@0: DUsbClientController* iController; sl@0: }; sl@0: sl@0: sl@0: /* sl@0: This is the EndpointInfo class used by the usb shared chunk client driver. sl@0: */ sl@0: sl@0: class TUsbcScEndpointInfo; sl@0: sl@0: sl@0: /** sl@0: Used to represent an array of (or inheriting from) TUsbcEndpointInfo objects. sl@0: sl@0: @see DUsbClientController::SetInterface sl@0: */ sl@0: sl@0: class TUsbcEndpointInfoArray sl@0: { sl@0: public: sl@0: typedef enum {EUsbcEndpointInfo, EUsbcScEndpointInfo} TArrayType; sl@0: sl@0: TUsbcEndpointInfoArray(const TUsbcEndpointInfo* aData, TInt aDataSize=0); sl@0: TUsbcEndpointInfoArray(const TUsbcScEndpointInfo* aData, TInt aDataSize=0); sl@0: inline TUsbcEndpointInfo& operator[](TInt aIndex) const; sl@0: sl@0: TArrayType iType; sl@0: private: sl@0: TUint8* iData; sl@0: TInt iDataSize; sl@0: }; sl@0: sl@0: class TUsbcRequestCallback; // todo?? required only for class below sl@0: sl@0: /** The USB Device software controller class. sl@0: sl@0: Implements the platform-independent layer (PIL), and defines the interface to the sl@0: platform-specific layer PSL). sl@0: sl@0: The implementation of the platform-specific layer interfaces with the hardware. sl@0: */ sl@0: class DUsbClientController : public DBase sl@0: { sl@0: friend class DUsbcPowerHandler; sl@0: friend TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint(); sl@0: // sl@0: // --- Platform Independent Layer (PIL) --- sl@0: // sl@0: sl@0: public: sl@0: sl@0: // sl@0: // --- The following functions constitute the PIL interface to the LDD --- sl@0: // sl@0: sl@0: virtual ~DUsbClientController(); sl@0: IMPORT_C void DisableClientStack(); sl@0: IMPORT_C void EnableClientStack(); sl@0: IMPORT_C TBool IsActive(); sl@0: IMPORT_C TInt RegisterClientCallback(TUsbcClientCallback& aCallback); sl@0: IMPORT_C static DUsbClientController* UsbcControllerPointer(TInt aUdc=0); sl@0: IMPORT_C void EndpointCaps(const DBase* aClientId, TDes8 &aCapsBuf) const; sl@0: IMPORT_C void DeviceCaps(const DBase* aClientId, TDes8 &aCapsBuf) const; sl@0: IMPORT_C TInt SetInterface(const DBase* aClientId, DThread* aThread, TInt aInterfaceNum, sl@0: TUsbcClassInfo& aClass, TDesC8* aString, TInt aTotalEndpointsUsed, sl@0: const TUsbcEndpointInfo aEndpointData[], TInt (*aRealEpNumbers)[6], sl@0: TUint32 aFeatureWord); sl@0: IMPORT_C TInt SetInterface(const DBase* aClientId, DThread* aThread, sl@0: TInt aInterfaceNum, TUsbcClassInfo& aClass, sl@0: TDesC8* aString, TInt aTotalEndpointsUsed, sl@0: const TUsbcEndpointInfoArray aEndpointData, sl@0: TInt aRealEpNumbers[], TUint32 aFeatureWord); sl@0: IMPORT_C TInt ReleaseInterface(const DBase* aClientId, TInt aInterfaceNum); sl@0: IMPORT_C TInt ReEnumerate(); sl@0: IMPORT_C TInt PowerUpUdc(); sl@0: IMPORT_C TInt UsbConnect(); sl@0: IMPORT_C TInt UsbDisconnect(); sl@0: IMPORT_C TInt RegisterForStatusChange(TUsbcStatusCallback& aCallback); sl@0: IMPORT_C TInt DeRegisterForStatusChange(const DBase* aClientId); sl@0: IMPORT_C TInt RegisterForEndpointStatusChange(TUsbcEndpointStatusCallback& aCallback); sl@0: IMPORT_C TInt DeRegisterForEndpointStatusChange(const DBase* aClientId); sl@0: IMPORT_C TInt GetInterfaceNumber(const DBase* aClientId, TInt& aInterfaceNum) const; sl@0: IMPORT_C TInt DeRegisterClient(const DBase* aClientId); sl@0: IMPORT_C TInt Ep0PacketSize() const; sl@0: IMPORT_C TInt Ep0Stall(const DBase* aClientId); sl@0: IMPORT_C void SendEp0StatusPacket(const DBase* aClientId); sl@0: IMPORT_C TUsbcDeviceState GetDeviceStatus() const; sl@0: IMPORT_C TEndpointState GetEndpointStatus(const DBase* aClientId, TInt aEndpointNum) const; sl@0: IMPORT_C TInt SetupReadBuffer(TUsbcRequestCallback& aCallback); sl@0: IMPORT_C TInt SetupWriteBuffer(TUsbcRequestCallback& aCallback); sl@0: IMPORT_C void CancelReadBuffer(const DBase* aClientId, TInt aRealEndpoint); sl@0: IMPORT_C void CancelWriteBuffer(const DBase* aClientId, TInt aRealEndpoint); sl@0: IMPORT_C TInt HaltEndpoint(const DBase* aClientId, TInt aEndpointNum); sl@0: IMPORT_C TInt ClearHaltEndpoint(const DBase* aClientId, TInt aEndpointNum); sl@0: IMPORT_C TInt SetDeviceControl(const DBase* aClientId); sl@0: IMPORT_C TInt ReleaseDeviceControl(const DBase* aClientId); sl@0: IMPORT_C TUint EndpointZeroMaxPacketSizes() const; sl@0: IMPORT_C TInt SetEndpointZeroMaxPacketSize(TInt aMaxPacketSize); sl@0: IMPORT_C TInt GetDeviceDescriptor(DThread* aThread, TDes8& aDeviceDescriptor); sl@0: IMPORT_C TInt SetDeviceDescriptor(DThread* aThread, const TDes8& aDeviceDescriptor); sl@0: IMPORT_C TInt GetDeviceDescriptorSize(DThread* aThread, TDes8& aSize); sl@0: IMPORT_C TInt GetConfigurationDescriptor(DThread* aThread, TDes8& aConfigurationDescriptor); sl@0: IMPORT_C TInt SetConfigurationDescriptor(DThread* aThread, const TDes8& aConfigurationDescriptor); sl@0: IMPORT_C TInt GetConfigurationDescriptorSize(DThread* aThread, TDes8& aSize); sl@0: IMPORT_C TInt SetOtgDescriptor(DThread* aThread, const TDesC8& aOtgDesc); sl@0: IMPORT_C TInt GetOtgDescriptor(DThread* aThread, TDes8& aOtgDesc) const; sl@0: IMPORT_C TInt GetOtgFeatures(DThread* aThread, TDes8& aFeatures) const; sl@0: IMPORT_C TInt GetCurrentOtgFeatures(TUint8& aFeatures) const; sl@0: IMPORT_C TInt RegisterForOtgFeatureChange(TUsbcOtgFeatureCallback& aCallback); sl@0: IMPORT_C TInt DeRegisterForOtgFeatureChange(const DBase* aClientId); sl@0: IMPORT_C TInt GetInterfaceDescriptor(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TDes8& aInterfaceDescriptor); sl@0: IMPORT_C TInt SetInterfaceDescriptor(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: const TDes8& aInterfaceDescriptor); sl@0: IMPORT_C TInt GetInterfaceDescriptorSize(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TDes8& aSize); sl@0: IMPORT_C TInt GetEndpointDescriptor(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, TDes8& aEndpointDescriptor); sl@0: IMPORT_C TInt SetEndpointDescriptor(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, const TDes8& aEndpointDescriptor); sl@0: IMPORT_C TInt GetEndpointDescriptorSize(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, TDes8& aSize); sl@0: IMPORT_C TInt GetDeviceQualifierDescriptor(DThread* aThread, TDes8& aDeviceQualifierDescriptor); sl@0: IMPORT_C TInt SetDeviceQualifierDescriptor(DThread* aThread, const TDes8& aDeviceQualifierDescriptor); sl@0: IMPORT_C TInt GetOtherSpeedConfigurationDescriptor(DThread* aThread, TDes8& aConfigurationDescriptor); sl@0: IMPORT_C TInt SetOtherSpeedConfigurationDescriptor(DThread* aThread, const TDes8& aConfigurationDescriptor); sl@0: IMPORT_C TInt GetCSInterfaceDescriptorBlock(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TDes8& aInterfaceDescriptor); sl@0: IMPORT_C TInt SetCSInterfaceDescriptorBlock(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: const TDes8& aInterfaceDescriptor, TInt aSize); sl@0: IMPORT_C TInt GetCSInterfaceDescriptorBlockSize(DThread* aThread, const DBase* aClientId, sl@0: TInt aSettingNum, TDes8& aSize); sl@0: IMPORT_C TInt GetCSEndpointDescriptorBlock(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, TDes8& aEndpointDescriptor); sl@0: IMPORT_C TInt SetCSEndpointDescriptorBlock(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, const TDes8& aEndpointDescriptor, sl@0: TInt aSize); sl@0: IMPORT_C TInt GetCSEndpointDescriptorBlockSize(DThread* aThread, const DBase* aClientId, TInt aSettingNum, sl@0: TInt aEndpointNum, TDes8& aSize); sl@0: IMPORT_C TInt GetStringDescriptorLangId(DThread* aThread, TDes8& aLangId); sl@0: IMPORT_C TInt SetStringDescriptorLangId(TUint16 aLangId); sl@0: IMPORT_C TInt GetManufacturerStringDescriptor(DThread* aThread, TDes8& aString); sl@0: IMPORT_C TInt SetManufacturerStringDescriptor(DThread* aThread, const TDes8& aString); sl@0: IMPORT_C TInt RemoveManufacturerStringDescriptor(); sl@0: IMPORT_C TInt GetProductStringDescriptor(DThread* aThread, TDes8& aString); sl@0: IMPORT_C TInt SetProductStringDescriptor(DThread* aThread, const TDes8& aString); sl@0: IMPORT_C TInt RemoveProductStringDescriptor(); sl@0: IMPORT_C TInt GetSerialNumberStringDescriptor(DThread* aThread, TDes8& aString); sl@0: IMPORT_C TInt SetSerialNumberStringDescriptor(DThread* aThread, const TDes8& aString); sl@0: IMPORT_C TInt RemoveSerialNumberStringDescriptor(); sl@0: IMPORT_C TInt GetConfigurationStringDescriptor(DThread* aThread, TDes8& aString); sl@0: IMPORT_C TInt SetConfigurationStringDescriptor(DThread* aThread, const TDes8& aString); sl@0: IMPORT_C TInt RemoveConfigurationStringDescriptor(); sl@0: IMPORT_C TInt GetStringDescriptor(DThread* aThread, TUint8 aIndex, TDes8& aString); sl@0: IMPORT_C TInt SetStringDescriptor(DThread* aThread, TUint8 aIndex, const TDes8& aString); sl@0: IMPORT_C TInt RemoveStringDescriptor(TUint8 aIndex); sl@0: IMPORT_C TInt AllocateEndpointResource(const DBase* aClientId, TInt aEndpointNum, sl@0: TUsbcEndpointResource aResource); sl@0: IMPORT_C TInt DeAllocateEndpointResource(const DBase* aClientId, TInt aEndpointNum, sl@0: TUsbcEndpointResource aResource); sl@0: IMPORT_C TBool QueryEndpointResource(const DBase* aClientId, TInt aEndpointNum, sl@0: TUsbcEndpointResource aResource); sl@0: IMPORT_C TInt EndpointPacketSize(const DBase* aClientId, TInt aEndpointNum); sl@0: sl@0: // sl@0: // --- Public (pure) virtual (implemented by PSL, used by LDD) --- sl@0: // sl@0: sl@0: /** Forces the UDC into a non-idle state to perform a USB remote wakeup operation. sl@0: sl@0: The PSL should first check the current value of iRmWakeupStatus_Enabled sl@0: to determine whether or not to actually send a Remote Wakeup. sl@0: sl@0: @see iRmWakeupStatus_Enabled sl@0: sl@0: @return KErrGeneral if Remote Wakeup feature is not enabled or an error is encountered, sl@0: KErrNone otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: IMPORT_C virtual TInt SignalRemoteWakeup() =0; sl@0: sl@0: /** Dumps the contents of (all or part of) the UDC registers to the serial console. sl@0: This is for debugging purposes only. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: IMPORT_C virtual void DumpRegisters() =0; sl@0: sl@0: /** Returns a pointer to the DFC queue that should be used by the USB LDD. sl@0: sl@0: @return A pointer to the DFC queue that should be used by the USB LDD. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: IMPORT_C virtual TDfcQue* DfcQ(TInt aUnit) =0; sl@0: sl@0: /** Returns information about the current operating speed of the UDC. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. sl@0: The default implementation in the PIL returns EFalse.) sl@0: sl@0: @return ETrue if the UDC is currently operating at High speed, EFalse sl@0: otherwise (i.e. controller is operating at Full speed). sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: IMPORT_C virtual TBool CurrentlyUsingHighSpeed(); sl@0: sl@0: // sl@0: // --- Public PIL functions --- sl@0: // sl@0: sl@0: DUsbClientController* RegisterUdc(TInt aUdc); sl@0: sl@0: protected: sl@0: sl@0: // sl@0: // --- Functions and data members provided by PIL, called by PSL --- sl@0: // sl@0: sl@0: TBool InitialiseBaseClass(TUsbcDeviceDescriptor* aDeviceDesc, sl@0: TUsbcConfigDescriptor* aConfigDesc, sl@0: TUsbcLangIdDescriptor* aLangId, sl@0: TUsbcStringDescriptor* aManufacturer =0, sl@0: TUsbcStringDescriptor* aProduct =0, sl@0: TUsbcStringDescriptor* aSerialNum =0, sl@0: TUsbcStringDescriptor* aConfig =0, sl@0: TUsbcOtgDescriptor* aOtgDesc =0); sl@0: DUsbClientController(); sl@0: TInt DeviceEventNotification(TUsbcDeviceEvent aEvent); sl@0: void EndpointRequestComplete(TUsbcRequestCallback* aCallback); sl@0: TInt Ep0RequestComplete(TInt aRealEndpoint, TInt aCount, TInt aError); sl@0: void MoveToAddressState(); sl@0: void SetCurrent(TInt aCurrent); sl@0: TUsbcEp0State EnquireEp0NextState(const TUint8* aSetupBuf) const; sl@0: TInt ProcessSetConfiguration(const TUsbcSetup& aPacket); sl@0: void HandleHnpRequest(TInt aHnpState); sl@0: sl@0: /** This info can be used by the PSL before sending ZLPs. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: TBool iEp0ReceivedNonStdRequest; sl@0: sl@0: /** True if RMW is currently enabled (set by either PIL or PSL). sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: TBool iRmWakeupStatus_Enabled; sl@0: sl@0: /** Ep0 incoming (rx) data is placed here (one packet). sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: TUint8 iEp0_RxBuf[KUsbcBufSzControl]; sl@0: sl@0: private: sl@0: sl@0: // sl@0: // --- Platform Specific Layer (PSL) --- sl@0: // sl@0: sl@0: /** This function will be called by the PIL upon decoding a SET_ADDRESS request. sl@0: sl@0: UDCs which require a manual setting of the USB device address should do that in this function. sl@0: sl@0: @param aAddress A valid USB device address that was received with the SET_ADDRESS request. sl@0: sl@0: @return KErrNone if address was set successfully or if this UDC's address cannot be set manually, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SetDeviceAddress(TInt aAddress) =0; sl@0: sl@0: /** Configures (enables) an endpoint (incl. Ep0) for data transmission or reception. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be enabled. sl@0: @param aEndpointInfo A reference to a properly filled-in endpoint info structure. sl@0: sl@0: @return KErrArgument if endpoint number or endpoint info invalid, KErrNone if endpoint sl@0: successfully configured, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo) =0; sl@0: sl@0: /** De-configures (disables) an endpoint (incl. Ep0). sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be disabled. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if endpoint successfully de-configured, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt DeConfigureEndpoint(TInt aRealEndpoint) =0; sl@0: sl@0: /** Allocates an endpoint resource. sl@0: sl@0: If the resource gets successfully allocated, it will be used from when the current bus transfer sl@0: has been completed. sl@0: sl@0: @param aRealEndpoint The number of the endpoint. sl@0: @param aResource The endpoint resource to be allocated. sl@0: sl@0: @return KErrNone if the resource has been successfully allocated, KErrNotSupported if the endpoint sl@0: does not support the resource requested, and KErrInUse if the resource is already consumed and sl@0: cannot be allocated. sl@0: sl@0: @publishedPartner @deprecated sl@0: */ sl@0: virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) =0; sl@0: sl@0: /** Deallocates (frees) an endpoint resource. sl@0: sl@0: The resource will be removed from when the current bus transfer has been completed. sl@0: sl@0: @param aRealEndpoint The number of the endpoint. sl@0: @param aResource The endpoint resource to be deallocated. sl@0: sl@0: @return KErrNone if the resource has been successfully deallocated, KErrNotSupported if the endpoint sl@0: does not support the resource requested. sl@0: sl@0: @publishedPartner @deprecated sl@0: */ sl@0: virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) =0; sl@0: sl@0: /** Queries the use of and endpoint resource. sl@0: sl@0: @param aRealEndpoint The number of the endpoint. sl@0: @param aResource The endpoint resource to be queried. sl@0: sl@0: @return ETrue if the specified resource is in use at the endpoint, EFalse if not. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const =0; sl@0: sl@0: /** Opens a DMA channel (if possible). sl@0: sl@0: @param aRealEndpoint The number of the endpoint for which to open the DMA channel. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if channel successfully opened or if sl@0: endpoint not DMA-capable, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt OpenDmaChannel(TInt aRealEndpoint); sl@0: sl@0: /** Closes a DMA channel (if possible). sl@0: sl@0: @param aRealEndpoint The number of the endpoint for which to close the DMA channel. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void CloseDmaChannel(TInt aRealEndpoint); sl@0: sl@0: /** Sets up a read request on an endpoint (excl. Ep0) for data reception. sl@0: sl@0: For endpoint 0 read requests, SetupEndpointZeroRead() is used instead. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: @param aCallback A reference to a properly filled-in request callback structure. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if read successfully set up, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) =0; sl@0: sl@0: /** Sets up a write request on an endpoint (excl. Ep0) for data transmission. sl@0: sl@0: For endpoint 0 write requests, SetupEndpointZeroWrite() is used instead. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: @param aCallback A reference to a properly filled-in request callback structure. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if write successfully set up, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) =0; sl@0: sl@0: /** Cancels a read request on an endpoint (excl. Ep0). sl@0: sl@0: Note that endpoint 0 read requests are never cancelled by the PIL, so sl@0: there is also no CancelEndpointZeroRead() function. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if read successfully cancelled, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt CancelEndpointRead(TInt aRealEndpoint) =0; sl@0: sl@0: /** Cancels a write request on an endpoint (incl. Ep0). sl@0: sl@0: The PIL calls this function also to cancel endpoint zero write requests. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if write successfully cancelled, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt CancelEndpointWrite(TInt aRealEndpoint) =0; sl@0: sl@0: /** Same as SetupEndpointRead(), but for endpoint zero only. sl@0: sl@0: No callback is used here as this function is only used internally by the PIL and no user side request sl@0: exists for it. The data buffer to be used (filled) is iEp0_RxBuf. sl@0: sl@0: @return KErrGeneral if (&iEndpoints[KEp0_Out]->iRxBuf != NULL) or some other error occurs, sl@0: KErrNone if read successfully set up. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SetupEndpointZeroRead() =0; sl@0: sl@0: /** Same as SetupEndpointWrite(), but for endpoint zero only. sl@0: sl@0: No callback is used here as this function is only used internally by the PIL and no user side request sl@0: exists for it. sl@0: sl@0: @param aBuffer This points to the beginning of the data to be sent. sl@0: @param aLength The number of bytes to be sent. sl@0: @param aZlpReqd ETrue if a zero-length packet (ZLP) is to be sent after the data. sl@0: sl@0: @return KErrGeneral if (&iEndpoints[KEp0_In]->iTxBuf != NULL) or some other error occurs, sl@0: KErrNone if write successfully set up. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd=EFalse) =0; sl@0: sl@0: /** Sets up on Ep0 the transmission of a single zero-length packet (ZLP). sl@0: sl@0: @return KErrNone if ZLP successfully set up, KErrGeneral otherwise.. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SendEp0ZeroByteStatusPacket() =0; sl@0: sl@0: /** Stalls an endpoint (incl. Ep0). sl@0: sl@0: Isochronous endpoints cannot be stalled. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be stalled. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if endpoint successfully stalled, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt StallEndpoint(TInt aRealEndpoint) =0; sl@0: sl@0: /** Clears the stall condition on an endpoint (incl. Ep0). sl@0: sl@0: Isochronous endpoints cannot be stalled. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be stalled. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if endpoint successfully de-stalled, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt ClearStallEndpoint(TInt aRealEndpoint) =0; sl@0: sl@0: /** Returns the stall status of an endpoint (incl. Ep0). sl@0: sl@0: Isochronous endpoints cannot be stalled. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: sl@0: @return KErrArgument if endpoint number invalid, 1 if endpoint is currently stalled, 0 if not. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt EndpointStallStatus(TInt aRealEndpoint) const =0; sl@0: sl@0: /** Returns the error status of an endpoint (incl. Ep0). sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if no error at this endpoint, sl@0: KErrGeneral if there is an error. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const =0; sl@0: sl@0: /** Resets the data toggle bit for an endpoint (incl. Ep0). sl@0: sl@0: Isochronous endpoints don't use data toggles. sl@0: sl@0: @param aRealEndpoint The number of the endpoint to be used. sl@0: sl@0: @return KErrArgument if endpoint number invalid, KErrNone if data toggle successfully reset, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt ResetDataToggle(TInt aRealEndpoint) =0; sl@0: sl@0: /** Returns the (11-bit) frame number contained in the last received SOF packet. sl@0: sl@0: This information is used for isochronous transfers. sl@0: sl@0: @return The (11-bit) frame number contained in the last received SOF packet. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt SynchFrameNumber() const =0; sl@0: sl@0: /** Stores the (11-bit) frame number that should be sent in response to the next SYNCH_FRAME request(s). sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void SetSynchFrameNumber(TInt aFrameNumber) =0; sl@0: sl@0: /** Starts the UDC. sl@0: sl@0: This initializes the device controller hardware before any other operation can be sl@0: performed. Tasks to be carried out here might include sl@0: - resetting the whole UDC design sl@0: - enabling the UDC's clock sl@0: - binding & enabling the UDC (primary) interrupt sl@0: - write meaningful values to some general UDC registers sl@0: - enabling the USB Reset interrupt sl@0: - enabling the UDC proper (for instance by setting an Enable bit) sl@0: sl@0: @return KErrNone if UDC successfully started, KErrGeneral if there was an error. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt StartUdc() =0; sl@0: sl@0: /** Stops the UDC. sl@0: sl@0: This basically makes undone what happened in StartUdc(). Tasks to be carried out sl@0: here might include: sl@0: - disabling the UDC proper (for instance by clearing an Enable bit) sl@0: - disabling the USB Reset interrupt sl@0: - disabling & unbinding the UDC (primary) interrupt sl@0: - disabling the UDC's clock sl@0: sl@0: @return KErrNone if UDC successfully stopped, KErrGeneral if there was an error. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt StopUdc() =0; sl@0: sl@0: /** Connects the UDC - and thus the USB device - physically to the bus. sl@0: sl@0: This might involve a call into the Variant DLL, as the mechanism to achieve the connection can be sl@0: specific to the platform (rather than UDC specific). Since this functionality is not part of the USB sl@0: specification it has to be explicitly supported, either by the UDC itself or by the hardware sl@0: platform. If it is supported, then the member function SoftConnectCaps should be implemented to return sl@0: ETrue. sl@0: sl@0: @see SoftConnectCaps() sl@0: sl@0: @return KErrNone if UDC successfully connected, KErrGeneral if there was an error. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt UdcConnect() =0; sl@0: sl@0: /** Disconnects the UDC - and thus the USB device - physically from the bus. sl@0: sl@0: This might involve a call into the Variant DLL, as the mechanism to achieve the disconnection can be sl@0: specific to the platform (rather than UDC specific). Since this functionality is not part of the USB sl@0: specification it has to be explicitly supported, either by the UDC itself or by the hardware sl@0: platform. If it is supported, then the member function SoftConnectCaps should be implemented to return sl@0: ETrue. sl@0: sl@0: @see SoftConnectCaps() sl@0: sl@0: @return KErrNone if UDC successfully disconnected, KErrGeneral if there was an error. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt UdcDisconnect() =0; sl@0: sl@0: /** Returns the USB cable connection status. sl@0: sl@0: @return ETrue if the device is connected (via the USB cable) to a USB host, EFalse if not. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool UsbConnectionStatus() const =0; sl@0: sl@0: /** Returns a truth value showing if the VBUS line is powered or not. sl@0: sl@0: Lack of power may indicate an unpowered host or upstream hub, or a disconnected cable. sl@0: sl@0: @return ETrue if VBUS is powered, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool UsbPowerStatus() const =0; sl@0: sl@0: /** Returns the current power status of the USB device. sl@0: sl@0: @return ETrue if the device is currently self-powered, EFalse if not. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool DeviceSelfPowered() const =0; sl@0: sl@0: /** Returns a pointer to an array of TUsbcEndpointCaps structures, which describe the endpoint sl@0: capabilities of this UDC. sl@0: sl@0: The dimension of the array can be obtained by calling the member function DeviceTotalEndpoints(). sl@0: Note that there might be gaps in the array, as the endpoints are numbered using the 'real endpoint' sl@0: numbering scheme. Here is how an array could look like: sl@0: sl@0: @code sl@0: static const TInt KUsbTotalEndpoints = 5; sl@0: static const TUsbcEndpointCaps DeviceEndpoints[KUsbTotalEndpoints] = sl@0: { sl@0: // UDC # iEndpoints index sl@0: {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirOut)}, // 0 - 0 sl@0: {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirIn )}, // 0 - 1 sl@0: {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present sl@0: {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 1 - 3 sl@0: {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)} // 2 - 4 sl@0: }; sl@0: @endcode sl@0: sl@0: For the endpoint max packet sizes on a USB 2.0 High-speed UDC, the PSL should provide sl@0: the overlaid values for both FS and HS, as the PIL can deduce the appropriate values sl@0: for either speed. sl@0: sl@0: @see TUsbcEndpointCaps sl@0: @see DeviceTotalEndpoints() sl@0: sl@0: @return A pointer to an array of TUsbcEndpointCaps structures, which describe the endpoint sl@0: capabilities of this UDC. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const =0; sl@0: sl@0: /** Returns the number of elements in the array pointed to by the return value of DeviceEndpointCaps(). sl@0: sl@0: Note that this is not necessarily equal to the number of usable endpoints. In the example to the sl@0: DeviceEndpointCaps() function, this value would be 5 even though there are only 4 endpoints. sl@0: sl@0: @see DeviceEndpointCaps() sl@0: sl@0: @return The number of elements in the array pointed to by the return value of DeviceEndpointCaps(). sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt DeviceTotalEndpoints() const =0; sl@0: sl@0: /** Returns a truth value indicating whether or not this UDC or platform has the capability to disconnect sl@0: and re-connect the USB D+ line under software control. sl@0: sl@0: @see UdcConnect() sl@0: @see UdcDisconnect() sl@0: sl@0: @return ETrue if software connect/disconnect is supported, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool SoftConnectCaps() const =0; sl@0: sl@0: /** Returns a truth value indicating whether or not this UDC allows the accurate tracking of the USB sl@0: device state. sl@0: sl@0: This capability affects how device state change notifications to the LDD/user are being handled. sl@0: sl@0: @return ETrue if this UDC allows the tracking of the USB device state, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool DeviceStateChangeCaps() const =0; sl@0: sl@0: /** Returns a truth value indicating whether the USB device controller (UDC) hardware supports sl@0: detection of a plugged-in USB cable even when not powered. sl@0: sl@0: This capability affects the power management strategy used by the USB Manager. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. sl@0: The default implementation in the PIL returns EFalse.) sl@0: sl@0: @return ETrue if this UDC supports USB cable detection when not powered, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool CableDetectWithoutPowerCaps() const; sl@0: sl@0: /** Returns a truth value indicating whether the USB device controller (UDC) hardware supports sl@0: USB High-speed operation. sl@0: sl@0: This capability affects driver functionality and behaviour throughout the implementation. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. sl@0: The default implementation in the PIL returns EFalse.) sl@0: sl@0: @return ETrue if this UDC supports USB High-speed operation, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool DeviceHighSpeedCaps() const; sl@0: sl@0: /** Returns a truth value indicating whether this PSL supports the new sl@0: ('V2') endpoint resource request scheme. sl@0: sl@0: This capability can be queried from the user-side and may determine the sl@0: way the USB application issues resource allocation requests. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. sl@0: The default implementation in the PIL returns EFalse.) sl@0: sl@0: @return ETrue if PSL supports the new endpoint resource request scheme, sl@0: EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool DeviceResourceAllocV2Caps() const; sl@0: sl@0: /** Returns a truth value indicating whether this UDC handles OTG HNP bus sl@0: connects/disconnects automatically in hardware. sl@0: sl@0: This capability will be queried by the PIL and determines the way the sl@0: PIL calls the functions behind the sl@0: iEnablePullUpOnDPlus / iDisablePullUpOnDPlus pointers. sl@0: sl@0: If HNP is handled by hardware (TBool = ETrue) then the PIL will (in sl@0: that order) sl@0: sl@0: 1) make calls to those function pointers dependent only on the sl@0: readiness or otherwise of user-side USB Client support (i.e. the Client sl@0: LDD calls DeviceConnectToHost() / DeviceDisconnectFromHost()), as sl@0: opposed to also evaluating Client PDD EnableClientStack() / sl@0: DisableClientStack() calls from the OTG driver. sl@0: sl@0: 2) delay its USB Reset processing incl. the notification of upper sl@0: layers (LDD + user-side), plus the initial setting up of an Ep0 read sl@0: until user-side USB Client support readiness has been signalled sl@0: (i.e. until after a call to DeviceConnectToHost()). sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with sl@0: existing USB PSLs. The default implementation in the PIL returns EFalse.) sl@0: sl@0: @return ETrue if UDC/PSL handles HNP connects/disconnects in hardware, sl@0: EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool DeviceHnpHandledByHardwareCaps() const; sl@0: sl@0: /** Implements anything the UDC (PSL) might require following bus Suspend signalling. sl@0: sl@0: This function gets called by the PIL after it has been notified (by the PSL) about the Suspend sl@0: condition. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void Suspend() =0; sl@0: sl@0: /** Implements anything the UDC (PSL) might require following bus Resume signalling. sl@0: sl@0: This function gets called by the PIL after it has been notified (by the PSL) about the Resume event. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void Resume() =0; sl@0: sl@0: /** Implements anything the UDC (PSL) might require following bus Reset signalling. sl@0: sl@0: This function gets called by the PIL after it has been notified (by the PSL) about the Reset event. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void Reset() =0; sl@0: sl@0: /** Called by the PIL to signal to the PSL that it has finished processing a received Setup packet (on sl@0: Ep0) and that the PSL can now prepare itself for the next Ep0 reception (for instance by re-enabling sl@0: the Ep0 interrupt). sl@0: sl@0: The reason for having this function is the situation where no Ep0 read has been set up by the user and sl@0: thus a received Setup packet cannot immediately be delivered to the user. Once the user however sets sl@0: up an Ep0 read, the PIL completes the request and eventually calls this function. This way we can sl@0: implement some sort of flow-control. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void Ep0ReadSetupPktProceed() =0; sl@0: sl@0: /** Called by the PIL to signal to the PSL that it has finished processing a received Ep0 data packet and sl@0: that the PSL can now prepare itself for the next Ep0 reception (for instance by re-enabling the Ep0 sl@0: interrupt). sl@0: sl@0: The reason for having this function is the situation where no Ep0 read has been set up by the user and sl@0: thus a received packet cannot immediately be delivered to the user. Once the user however sets up an sl@0: Ep0 read, the PIL completes the request and eventually calls this function. This way we can implement sl@0: some sort of flow-control. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual void Ep0ReceiveProceed() =0; sl@0: sl@0: /** Returns a truth value indicating whether the USB controller hardware (UDC) supports being powered sl@0: down while (a configuration is) active. sl@0: sl@0: This capability affects the power management strategy used by the USB Manager. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. The default sl@0: implementation in the PIL - to be on the safe side - returns EFalse.) sl@0: sl@0: @return ETrue if this UDC supports power-down while active, EFalse otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TBool PowerDownWhenActive() const; sl@0: sl@0: /** Powers the UDC down, i.e. puts it into a (hardware-dependent) power-saving mode. Note that this sl@0: function is not the same as StopUdc(). The difference is that while StopUdc() effectively turns the sl@0: UDC off and so may invalidate all its settings, after a call to PowerDown() the UDC is expected to sl@0: return to its previous state when PowerUp() is called. This function is also not the same as sl@0: Suspend() which gets called by the PIL in response to a Suspend event on the bus, and only then sl@0: (but apart from that the two functions are very similar). sl@0: sl@0: This function won't be called by the PIL once the UDC is active if PowerDownWhenActive() returns sl@0: EFalse (which it by default does). sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. The default sl@0: implementation in the PIL does nothing.) sl@0: sl@0: @see PowerUp() sl@0: @see PowerDownWhenActive() sl@0: sl@0: @return KErrNone if UDC was successfully powered down, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt PowerDown(); sl@0: sl@0: /** Powers the UDC up by exiting a (hardware-dependent) power-saving mode. Note that this function is not sl@0: the same as StartUdc(). The difference is that while StartUdc() starts the UDC from zero and merely sl@0: leads to the default state (i.e. not an active configuration), after a call to PowerUp() the UDC is sl@0: expected to have returned to the state it was in before PowerDown() was called. sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. The default sl@0: implementation in the PIL does nothing.) sl@0: sl@0: @see PowerDown() sl@0: sl@0: @return KErrNone if UDC was successfully powered up, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt PowerUp(); sl@0: sl@0: /** Puts the controller into a specific test mode (during HS operation only). sl@0: sl@0: 9.4.9 Set Feature: "The transition to test mode must be complete no later than 3 ms after the sl@0: completion of the status stage of the request." (The status stage will have been completed sl@0: immediately before this function gets called.) sl@0: sl@0: (Function is not 'pure virtual' for backwards compatibility with existing USB PSLs. sl@0: The default implementation in the PIL returns KErrNotSupported.) sl@0: sl@0: @param aTestSelector The specific test mode selector (@see usb.h). sl@0: sl@0: @return KErrNone if the specified test mode was entered successfully, sl@0: KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt EnterTestMode(TInt aTestSelector); sl@0: sl@0: /** Turn on USB client functionality in an OTG/Host setup. sl@0: sl@0: This PSL function is called by the PIL when the OTG stack calls the PIL sl@0: function EnableClientStack(). Immediately afterwards the PIL may sl@0: connect the B-device to the bus (via the OTG stack). OtgEnableUdc() is sl@0: called always after StartUdc(). sl@0: sl@0: There is no equivalent to this function in the non-OTG version of the sl@0: USB PDD. sl@0: sl@0: @return KErrNone if UDC successfully enabled, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt OtgEnableUdc(); sl@0: sl@0: /** Turn off USB client functionality in an OTG/Host setup. sl@0: sl@0: This function is called by the PIL when the OTG stack calls the PIL sl@0: function DisableClientStack(); the PIL will do this immediately after sl@0: it has disconnected the B-device from the bus (via the OTG stack) and sl@0: before calling StopUdc(). sl@0: sl@0: There is no equivalent to this function in the non-OTG version of the sl@0: USB PDD. sl@0: sl@0: @return KErrNone if UDC successfully disabled, KErrGeneral otherwise. sl@0: sl@0: @publishedPartner @released sl@0: */ sl@0: virtual TInt OtgDisableUdc(); sl@0: sl@0: private: sl@0: sl@0: // sl@0: // --- Private member functions (used by PIL) --- sl@0: // sl@0: sl@0: TInt DeRegisterClientCallback(const DBase* aClientId); sl@0: TBool CheckEpAvailability(TInt aEndpointsUsed, const TUsbcEndpointInfoArray& aEndpointData, TInt aIfcNumber) sl@0: const; sl@0: TUsbcInterface* CreateInterface(const DBase* aClientId, TInt aIfc, TUint32 aFeatureWord); sl@0: TInt CreateEndpoints(TUsbcInterface* aIfc, TInt aEndpointsUsed, const TUsbcEndpointInfoArray& aEndpointData, sl@0: TInt *aRealEpNumbers); sl@0: TInt SetupIfcDescriptor(TUsbcInterface* aIfc, TUsbcClassInfo& aClass, DThread* aThread, TDesC8* aString, sl@0: const TUsbcEndpointInfoArray& aEndpointData); sl@0: TInt ClientId2InterfaceNumber(const DBase* aClientId) const; sl@0: TUsbcInterfaceSet* ClientId2InterfacePointer(const DBase* aClientId) const; sl@0: const DBase* InterfaceNumber2ClientId(TInt aIfcSet) const; sl@0: TUsbcInterfaceSet* InterfaceNumber2InterfacePointer(TInt aIfcSet) const; sl@0: inline const DBase* PEndpoint2ClientId(TInt aRealEndpoint) const; sl@0: inline TInt PEndpoint2LEndpoint(TInt aRealEndpoint) const; sl@0: TInt ActivateHardwareController(); sl@0: void DeActivateHardwareController(); sl@0: void DeleteInterfaceSet(TInt aIfcSet); sl@0: void DeleteInterface(TInt aIfcSet, TInt aIfc); sl@0: void CancelTransferRequests(TInt aRealEndpoint); sl@0: void DeleteRequestCallback(const DBase* aClientId, TInt aEndpointNum, TTransferDirection aTransferDir); sl@0: void DeleteRequestCallbacks(const DBase* aClientId); sl@0: void StatusNotify(TUsbcDeviceState aState, const DBase* aClientId=NULL); sl@0: void EpStatusNotify(TInt aRealEndpoint); sl@0: void OtgFeaturesNotify(); sl@0: void RunClientCallbacks(); sl@0: void ProcessDataTransferDone(TUsbcRequestCallback& aRcb); sl@0: void NextDeviceState(TUsbcDeviceState aNextState); sl@0: TInt ProcessSuspendEvent(); sl@0: TInt ProcessSuspendEventProceed(); sl@0: TInt ProcessResumeEvent(); sl@0: TInt ProcessResetEvent(TBool aPslUpcall=ETrue); sl@0: TInt ProcessCableInsertEvent(); sl@0: TInt ProcessCableRemoveEvent(); sl@0: TInt ProcessEp0ReceiveDone(TInt aCount); sl@0: TInt ProcessEp0TransmitDone(TInt aCount, TInt aError); sl@0: TInt ProcessEp0SetupReceived(TInt aCount); sl@0: TInt ProcessEp0DataReceived(TInt aCount); sl@0: TInt ProcessGetDeviceStatus(const TUsbcSetup& aPacket); sl@0: TInt ProcessGetInterfaceStatus(const TUsbcSetup& aPacket); sl@0: TInt ProcessGetEndpointStatus(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetClearDevFeature(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetClearIfcFeature(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetClearEpFeature(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetAddress(const TUsbcSetup& aPacket); sl@0: TInt ProcessGetDescriptor(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetDescriptor(const TUsbcSetup& aPacket); sl@0: TInt ProcessGetConfiguration(const TUsbcSetup& aPacket); sl@0: TInt ProcessGetInterface(const TUsbcSetup& aPacket); sl@0: TInt ProcessSetInterface(const TUsbcSetup& aPacket); sl@0: TInt ProcessSynchFrame(const TUsbcSetup& aPacket); sl@0: void ProceedSetDescriptor(); sl@0: void SetClearHaltFeature(TInt aRealEndpoint, TUint8 aRequest); sl@0: TInt ClearHaltFeature(TInt aRealEndpoint); sl@0: void ChangeConfiguration(TUint16 aValue); sl@0: void InterfaceSetup(TUsbcInterface* aIfc); sl@0: void InterfaceSetTeardown(TUsbcInterfaceSet* aIfc); sl@0: void ChangeInterface(TUsbcInterface* aIfc); sl@0: TInt DoForEveryEndpointInUse(TInt (DUsbClientController::*aFunction)(TInt), TInt& aCount); sl@0: void EnterFullSpeed(); sl@0: void EnterHighSpeed(); sl@0: TInt EvaluateOtgConnectFlags(); sl@0: inline const TUsbcConfiguration* CurrentConfig() const; sl@0: inline TUsbcConfiguration* CurrentConfig(); sl@0: inline TBool InterfaceExists(TInt aNumber) const; sl@0: inline TBool EndpointExists(TUint aAddress) const; sl@0: inline void Buffer2Setup(const TAny* aBuf, TUsbcSetup& aSetup) const; sl@0: inline TUint EpIdx2Addr(TUint aRealEndpoint) const; sl@0: inline TUint EpAddr2Idx(TUint aAddress) const; sl@0: inline void SetEp0DataOutVars(const TUsbcSetup& aPacket, const DBase* aClientId = NULL); sl@0: inline void ResetEp0DataOutVars(); sl@0: inline TBool IsInTheStatusList(const TUsbcStatusCallback& aCallback); sl@0: inline TBool IsInTheEpStatusList(const TUsbcEndpointStatusCallback& aCallback); sl@0: inline TBool IsInTheOtgFeatureList(const TUsbcOtgFeatureCallback& aCallback); sl@0: inline TBool IsInTheRequestList(const TUsbcRequestCallback& aCallback); sl@0: static void ReconnectTimerCallback(TAny* aPtr); sl@0: static void CableStatusTimerCallback(TAny* aPtr); sl@0: static void PowerUpDfc(TAny* aPtr); sl@0: static void PowerDownDfc(TAny* aPtr); sl@0: sl@0: private: sl@0: sl@0: // sl@0: // --- Private data members --- sl@0: // sl@0: sl@0: static DUsbClientController* UsbClientController[KUsbcMaxUdcs]; sl@0: sl@0: TInt iDeviceTotalEndpoints; // number of endpoints reported by PSL sl@0: TInt iDeviceUsableEndpoints; // number of endpoints reported to LDD sl@0: TUsbcDeviceState iDeviceState; // states as of USB spec chapter 9.1 sl@0: TUsbcDeviceState iDeviceStateB4Suspend; // state before entering suspend state sl@0: TBool iSelfPowered; // true if device is capable of beeing self-powered sl@0: TBool iRemoteWakeup; // true if device is capable of signalling rmwakeup sl@0: TBool iTrackDeviceState; // true if we should track the device state in s/w sl@0: TBool iHardwareActivated; // true if controller silicon is in operating state sl@0: TBool iOtgSupport; // true if OTG is supported by this device sl@0: TBool iOtgHnpHandledByHw; // true if HNP dis/connect is handled by hardware sl@0: TUint8 iOtgFuncMap; // bitmap indicating OTG extension features sl@0: TBool iHighSpeed; // true if currently operating at high-speed sl@0: TUsbcSetup iSetup; // storage for a setup packet during its DATA_OUT sl@0: TInt iEp0MaxPacketSize; // currently configured max packet size for Ep0 sl@0: const DBase* iEp0ClientId; // see comment at the begin of ps_usbc.cpp sl@0: TUint16 iEp0DataReceived; // indicates how many bytes have already been received sl@0: TBool iEp0DataReceiving; // true if ep0's in DATA_OUT stage sl@0: TBool iEp0WritePending; // true if a write on ep0 has been set up sl@0: TBool iEp0ClientDataTransmitting; // true if ep0's in DATA_IN on behalf of a client sl@0: const DBase* iEp0DeviceControl; // Device Ep0 requests are delivered to this LDD sl@0: TUsbcDescriptorPool iDescriptors; // the descriptors as of USB spec chapter 9.5 sl@0: TUint8 iCurrentConfig; // bConfigurationValue of current Config (1-based!) sl@0: RPointerArray iConfigs; // the root of the modelled USB device sl@0: TUsbcPhysicalEndpoint iRealEndpoints[KUsbcEpArraySize]; // array will be filled once at startup sl@0: TUint8 iEp0_TxBuf[KUsbcBufSz_Ep0Tx]; // ep0 outgoing (tx) data is placed here sl@0: #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST sl@0: TUint8 iEp0_RxCollectionBuf[KUsbcBufSz_Ep0Rx]; // used for (optional) SET_DESCRIPTOR request sl@0: #endif sl@0: TInt iEp0_RxExtraCount; // number of bytes received but not yet delivered sl@0: TBool iEp0_RxExtraData; // true if iEp0_RxExtraCount is valid sl@0: TInt iEp0_TxNonStdCount; // number of bytes requested by non-std Ep0 request sl@0: TUsbcRequestCallback* iRequestCallbacks[KUsbcEpArraySize]; // xfer requests; indexed by real ep number sl@0: TSglQue iEp0ReadRequestCallbacks; // list of ep0 read requests sl@0: TSglQue iClientCallbacks; // registered LDD clients and their callback functions sl@0: TSglQue iStatusCallbacks; // list of device state notification requests sl@0: TSglQue iEpStatusCallbacks; // list of endpoint state notification requests sl@0: TSglQue iOtgCallbacks; // list of OTG feature change requests sl@0: NTimer iReconnectTimer; // implements USB re-enumeration delay sl@0: NTimer iCableStatusTimer; // implements USB cable status detection delay sl@0: DUsbcPowerHandler* iPowerHandler; // pointer to USB power handler object sl@0: sl@0: protected: sl@0: TDfc iPowerUpDfc; // queued by power handler upon power-up sl@0: TDfc iPowerDownDfc; // queued by power handler upon power-down sl@0: sl@0: private: sl@0: TBool iStandby; // toggled by power handler as appropriate sl@0: TBool iStackIsActive; // client stack's function is usable sl@0: TBool iOtgClientConnect; // OTG stack wishes to connect to the host sl@0: TBool iClientSupportReady; // user-side USB Client support is loaded & active sl@0: TBool iDPlusEnabled; // set if both sides agree and DPLUS is asserted sl@0: TBool iUsbResetDeferred; // set when user-side wasn't ready yet sl@0: sl@0: public: sl@0: TInt (*iEnablePullUpOnDPlus)(TAny* aOtgContext); // these are to be filled in by the Host component sl@0: TInt (*iDisablePullUpOnDPlus)(TAny* aOtgContext); // in an OTG setup (otherwise unused) sl@0: TAny* iOtgContext; // to be passed into the above 2 functions sl@0: }; sl@0: sl@0: sl@0: /** Simple queue of status changes to be recorded. sl@0: Items are fetched by userside when able. sl@0: */ sl@0: class TUsbcDeviceStatusQueue sl@0: { sl@0: public: sl@0: TUsbcDeviceStatusQueue(); sl@0: void AddStatusToQueue(TUint32 aDeviceStatus); sl@0: TInt GetDeviceQueuedStatus(TUint32& aDeviceStatus); sl@0: void FlushQueue(); sl@0: sl@0: private: sl@0: TUint32 iDeviceStatusQueue[KUsbDeviceStatusQueueDepth]; sl@0: TInt iStatusQueueHead; sl@0: }; sl@0: sl@0: #include sl@0: sl@0: #endif // __USBCSHARED_H__ sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: