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