--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usb_plat/usb_shai_api/inc/usb_peripheral_shai.h Tue Aug 31 17:01:47 2010 +0300
@@ -0,0 +1,1181 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+/** @file
+
+ @brief USB Peripheral SHAI header
+
+ @version 0.3.0
+
+ Abstract interface for USB Peripheral Controller.
+
+ @publishedDeviceAbstraction
+
+ */
+
+#ifndef USB_PERIPHERAL_SHAI_H
+#define USB_PERIPHERAL_SHAI_H
+
+// System includes
+#include <kern_priv.h>
+#include <usb/usb_common_shai.h> // Common types shared between the USB SHAIs
+#include <usb/usb_peripheral_shai_shared.h> // Common types shared with upper layers
+
+/**
+ * This macro specifies the version of the USB Peripheral SHAI header
+ * in binary coded decimal format. This allows the PSL layer to
+ * confirm a certain definition is available, if needed. This can for
+ * example make it possible for a new PSL to support compilation in an
+ * older environment with old USB SHAI version that is missing some
+ * new definitions.
+ */
+#define USB_PERIPHERAL_SHAI_VERSION 0x030
+
+// The namespace is documented in file usb_common_shai.h, so it is not
+// repeated here
+namespace UsbShai
+ {
+ /**
+ * Masks defined for TUsbPeripheralEndpointCaps.iSizes.
+ *
+ * Zero means this endpoint is not available (= no size).
+ */
+ const TUint KUsbEpNotAvailable = 0x00000000;
+
+ /**
+ * Max packet size is continuously variable up to some size specified.
+ * (Interrupt and Isochronous endpoints only.)
+ */
+ const TUint KUsbEpSizeCont = 0x00000001;
+
+ /** Max packet size 8 bytes is supported */
+ const TUint KUsbEpSize8 = 0x00000008;
+
+ /** Max packet size 16 bytes is supported */
+ const TUint KUsbEpSize16 = 0x00000010;
+
+ /** Max packet size 32 bytes is supported */
+ const TUint KUsbEpSize32 = 0x00000020;
+
+ /** Max packet size 64 bytes is supported */
+ const TUint KUsbEpSize64 = 0x00000040;
+
+ /** Max packet size 128 bytes is supported */
+ const TUint KUsbEpSize128 = 0x00000080;
+
+ /** Max packet size 256 bytes is supported */
+ const TUint KUsbEpSize256 = 0x00000100;
+
+ /** Max packet size 512 bytes is supported */
+ const TUint KUsbEpSize512 = 0x00000200;
+
+ /** Max packet size 1023 bytes is supported */
+ const TUint KUsbEpSize1023 = 0x00000400;
+
+ /** Max packet size 1024 bytes is supported */
+ const TUint KUsbEpSize1024 = 0x00000800;
+
+ /**
+ * Test Mode Selectors (Set/ClearFeature)
+ * Refer to usb specification 2.0, Chapter 9.4.9, table 9-7
+ */
+ enum TUsbTestModeSelector
+ {
+ EUsbTestSelector_Test_J = 0x01,
+ EUsbTestSelector_Test_K,
+ EUsbTestSelector_Test_SE0_NAK,
+ EUsbTestSelector_Test_Packet,
+ EUsbTestSelector_Test_Force_Enable
+ };
+
+ /**
+ * Transfer direction of a USB transfer request.
+ * @see TUsbPeripheralRequest
+ */
+ enum TTransferDirection
+ {
+ EControllerNone,
+ EControllerRead,
+ EControllerWrite
+ };
+
+ /**
+ * Enumeration listing the event codes that are passed from PSL to
+ * PIL to indicate peripheral events
+ */
+ enum TUsbPeripheralEvent
+ {
+ /** The USB Suspend bus state has been detected.
+ *
+ * When the Peripheral Controller PSL is part of an
+ * OTG-capable port, the PSL shall report this event also when
+ * operating as the A-peripheral, in which case this final
+ * suspend event starts the HNP role switch back to A-host.
+ */
+ EUsbEventSuspend,
+
+ /** USB Resume signaling has been detected. */
+ EUsbEventResume,
+
+ /** A USB Reset condition has been detected. */
+ EUsbEventReset,
+
+ /**
+ * VBUS level has risen above the B-session valid threshold. This
+ * is only relevant for a stand-alone peripheral controllers
+ * (those not associated with an OTG port). For an OTG port, the
+ * VBUS state is reported to PIL layer by the OTG Controller PSL.
+ */
+ EUsbEventVbusRisen,
+
+ /**
+ * VBUS level has fallen below the B-session valid threshold. This
+ * is only relevant for a stand-alone peripheral controllers
+ * (those not associated with an OTG port). For an OTG port, the
+ * VBUS state is reported to PIL layer by the OTG Controller PSL.
+ */
+ EUsbEventVbusFallen
+ };
+
+ typedef TUint32 TUsbPeripheralPacketArray;
+
+ /**
+ * @brief A USB transfer request.
+ *
+ * This class will be constructed in PIL or upper layer, and be
+ * passed down to PSL. After the request was done, PSL layer will
+ * modify corresponding members (like data length, packet info
+ * etc.) and re-pass it back to PIL via interface
+ * MUsbPeripheralPilCallbackIf::EndpointRequestComplete().
+ *
+ */
+ NONSHARABLE_CLASS(TUsbPeripheralRequest)
+ {
+ public:
+ /**
+ * This class doesn't need a destructor because it has nothing to be
+ * freed, closed, destroyed. It 'owns' nothing.
+ */
+ IMPORT_C TUsbPeripheralRequest(TInt aRealEpNum);
+
+ public:
+ /** The 'real' endpoint number this request to be bind to. */
+ TInt iRealEpNum;
+
+ /**
+ * Start address of this buffer. Filled-in by PIL.
+ *
+ * PSL needs to put received data in this buffer if it's a read request.
+ * PSL needs to get data from this buffer if it is a write request.
+ */
+ TUint8* iBufferStart;
+
+ /** Physical address of buffer start (used for DMA). */
+ TUintPtr iBufferAddr;
+
+ /** Length in bytes to be read/write. Filled-in by PIL. */
+ TInt iLength;
+
+ /**
+ * Number of bytes transmitted (if it is a write);
+ * This value need to be updated by PSL.
+ */
+ TUint iTxBytes;
+
+ /**
+ * Number of packets received (if it is a read);
+ * This value need to be updated by PSL.
+ */
+ TUint iRxPackets;
+
+ /**
+ * This is a re-interpretation of what's inside in buffer iBufferStart.
+ * It is designed to be that the first packet always contains all the
+ * bytes received. So only the following scenario are possible:
+ *
+ * 1. Nothing, iRxPackets is zero, no packet received.
+ *
+ * 2. 1 data Packet, iRxPackets is one.
+ * iPacketIndex[0] is the offset against iBufferStart of where the
+ * first byte of received data begins.
+ * iPacketSize[0] is the size (in bytes) of the received data.
+ *
+ * 3. 1 data packet, and one ZLP packet, iRxPackets is two.
+ * iPacketIndex[0] is the offset against iBufferStart of where the
+ * first byte of received data begins.
+ * iPacketSize[0] is the size (in bytes) of the data packet.
+ *
+ * iPacketIndex[1] is the offset of the ZLP packet.
+ * iPacketSize[1] is always set to zero since ZLP contains no data.
+ *
+ */
+ TUsbPeripheralPacketArray* iPacketIndex;
+
+ /** Array of packet sizes. Details see iPacketIndex */
+ TUsbPeripheralPacketArray* iPacketSize;
+
+ /**
+ * Indicates the transfer direction of this request.
+ * Note, SetupEndpointRead/Write likewise functions already point out
+ * the transfer direction, PSL may select to use it or not.
+ */
+ TTransferDirection iTransferDir;
+
+ /**
+ * For EControllerWrite (IN) transfers, it is used to Indicates that if
+ * a Zero Length Packet is required at the end of this transfer.
+ * It will be set to ETrue if ZLP is needed, EFalse otherwise.
+ */
+ TBool iZlpReqd;
+
+ /**
+ * The error code upon completion of the request;
+ * PSL need to set it to KErrNone if no errors, Set it to other
+ * system error codes otherwise.
+ */
+ TInt iError;
+ };
+
+ /**
+ * Peripheral controller capabilities.
+ *
+ * PSL should use those values to fill in data member iControllerCaps in
+ * structure TPeripheralControllerProperties.
+ *
+ * @see TPeripheralControllerProperties.
+ */
+ typedef TUint32 TDeviceCaps;
+
+ /**
+ * Indicates whether peripheral controller hardware supports USB High-speed.
+ * This capability affects driver functionality and behavior throughout the
+ * implementation.
+ *
+ * Set this bit if this peripheral controller supports USB High-speed;
+ * Clear it otherwise.
+ */
+ const TDeviceCaps KDevCapHighSpeed = 0x00000001;
+
+ /**
+ * Indicates whether the peripheral controller supports hardware acceleration
+ * for setting the device address, i.e. automatically setting device address
+ * on conclusion of status phase of SET_ADDRESS.
+ *
+ * If this capability is supported PIL will call SetDeviceAddress() before
+ * sending a zero byte status packet.
+ *
+ * Set this bit if hardware acceleration is supported.
+ * Clear it otherwise.
+ */
+ const TDeviceCaps KDevCapSetAddressAcceleration = 0x00000002;
+
+ /**
+ * Indicates whether controller support Session Request Protocol.
+ *
+ * Set this bit if SRP is supported.
+ * Clear it otherwise.
+ */
+ const TDeviceCaps KDevCapSrpSupport = 0x00000004;
+
+ /**
+ * Indicates whether controller support Host Negotiation Protocol.
+ *
+ * Set this bit if HNP is supported.
+ * Clear it otherwise.
+ */
+ const TDeviceCaps KDevCapHnpSupport = 0x00000008;
+
+ /**
+ * Indicates whether controller support Remote wakeup
+ *
+ * Set this bit if remote wakeup is supported.
+ * Clear it otherwise.
+ */
+ const TDeviceCaps KDevCapRemoteWakeupSupport = 0x00000010;
+
+ /**
+ * Configuration data from PSL to PIL when register a controller through
+ * interface UsbPeripheralPil::RegisterPeripheralController().
+ */
+ NONSHARABLE_CLASS(TPeripheralControllerProperties)
+ {
+ public:
+ TPeripheralControllerProperties();
+
+ public: // Data
+ /**
+ * A bitmap used to Indicates the capabilities of this controller.
+ * PSL should set the corresponding bit to '1' if one capability is
+ * supported by this controller.
+ */
+ TDeviceCaps iControllerCaps;
+
+ /**
+ * Pointer to a DFC queue that will be used for DFCs of this controller.
+ *
+ * A stand-alone (one not associated with an OTG-port) peripheral PSL
+ * implementation must supply a pointer to a dedicated DFC queue that
+ * has been created for this controller. Both the PSL itself and the PIL
+ * layer must queue their DFCs for this controller in this DFC queue to
+ * ensure the code is running in the same context.
+ *
+ * A peripheral PSL that is part of an OTG port will be registered by
+ * the OTG PSL. In this case, the DFC queue supplied here must be the
+ * same DFC queue as the one supplied in the properties of the OTG
+ * Controller.
+ */
+ TDfcQue* iDfcQueue;
+
+ /**
+ * Describe the capabilities of all endpoint owned by this controller.
+ *
+ * Note that there might be gaps in the array, because the endpoints
+ * must be numbered by using the 'real endpoint' numbering scheme.
+ *
+ * An example of end point capability array:
+ *
+ * @code
+ * static const TUsbPeripheralEndpointCaps DevEndpointCaps[KTotalEps] =
+ * {
+ * // MaxSize mask , Types&Dir , High ,Reserved
+ * speed?
+ * {KEp0MaxPktSzMask,(KUsbEpTypeControl | KUsbEpDirOut), ETrue ,0 , 0},
+ * {KEp0MaxPktSzMask,(KUsbEpTypeControl | KUsbEpDirIn ), ETrue ,0 , 0},
+ *
+ * {KUsbEpNotAvailable,KUsbEpNotAvailable , ETrue ,0 , 0},
+ *
+ * {KBlkMaxPktSzMask,(KUsbEpTypeBulk | KUsbEpDirIn ) , ETrue ,0 , 0},
+ * {KBlkMaxPktSzMask,(KUsbEpTypeBulk | KUsbEpDirOut) , ETrue ,0 , 0}
+ * };
+ * @endcode
+ *
+ * For endpoint maxinum packet size on USB2.0 High-speed, PSL should
+ * provide the overlaid values for both full speed and high speed, as
+ * PIL can deduce the appropriate values for either speed.
+ *
+ */
+ const TUsbPeripheralEndpointCaps* iDeviceEndpointCaps;
+
+ /**
+ * Set by the PSL to indicate the number of entries in
+ * iDeviceEndpointCaps array.
+ * Be noted that this value include the ones that are marked as
+ * KUsbEpNotAvailable in table iDeviceEndpointCaps.
+ */
+ TInt iDeviceTotalEndpoints;
+
+ /**
+ * Maximum size of ep0 packet.
+ * @see USB spec 2.0, chapter 9, table 9-8.
+ */
+ TUint8 iMaxEp0Size;
+
+ /**
+ * Device Release number in binary-coded decimal.
+ * @see USB spec 2.0, chapter 9, table 9-8.
+ */
+ TUint16 iDeviceRelease;
+ };
+
+ /**
+ * Enumeration of stages within a control transfer
+ *
+ * Possible stages defined in USB spec include:
+ * 1. setup -> status in
+ * 2. setup -> data in -> status out
+ * 3. setup -> data out -> status in
+ */
+ enum TControlStage
+ {
+ /**
+ * Control transfer always start with a setup stage in which a setup
+ * packet is expected.
+ */
+ EControlTransferStageSetup,
+
+ /** The stage that a data packet is expected from be received */
+ EControlTransferStageDataOut,
+
+ /**
+ * Status in stage can either following a Setup stage (if no data stage)
+ * or following a data out stage.
+ */
+ EControlTransferStageStatusIn,
+
+ /**
+ * Depends on the request type of a setup packet, a data in stage maybe
+ * followed after a setup packet.
+ *
+ * Within this stage we expect upper/ourself to send some data to host.
+ */
+ EControlTransferStageDataIn,
+
+ /**
+ * This is an optional stage, some controller will silently swallow
+ * Status out packet and not able to report it.
+ * PIL has consider this situation when control transfer state machine
+ * is introduced.
+ */
+ EControlTransferStageStatusOut,
+
+ EControlTransferStageMax
+ };
+
+ /**
+ * Packet types in control transfers.
+ *
+ * PSL need to tell PIL about the types of each packet it received.
+ * @see MUsbPeripheralPilCallbackIf::Ep0RequestComplete().
+ */
+ enum TControlPacketType
+ {
+ /** Indicates a setup packet */
+ EControlPacketTypeSetup,
+
+ /** Indicates a data out packet */
+ EControlPacketTypeDataOut,
+
+ /**
+ * Indicates a status in packet.
+ * optional, PSL can select not to complete this packet.
+ */
+ EControlPacketTypeStatusIn,
+
+ /** Indicates a data in packet */
+ EControlPacketTypeDataIn,
+
+ /**
+ * Indicates that a status out packet.
+ * optional, PSL can select not to complete this packet.
+ */
+ EControlPacketTypeStatusOut,
+
+ };
+
+ /**
+ * @brief Interface for PSL to do callback to PIL
+ *
+ * This is the interface that a PSL need talk with PIL in order to:
+ * 1. Pass device event (reset/suspend/resume/vbus high/vbus low etc) to PIL.
+ * 2. Complete a read/write request to PIL.
+ * 3. Query control transfer stage from PIL.
+ * 3. Other functions like SetAdress/Handle HNP/Get remote wake up etc.
+ *
+ * This interface already been implemented and exported via library
+ * usbperipheralpil.lib. PSL need to add this library as a dependency in
+ * you PSL .mmp file.
+ *
+ * @lib usbperipheralpil.lib
+ */
+ NONSHARABLE_CLASS(MUsbPeripheralPilCallbackIf)
+ {
+ public:
+ /**
+ * Used to synchronize the Ep0 Stage machine between PSL and PIL.
+ * Accepts a SETUP packet and returns the next Ep0 Stage.
+ *
+ * This function will NOT lead anything to be changed at PIL, it is
+ * functioning by parsing the supplied buffer only.
+ *
+ * @param aSetupBuf The SETUP packet received by PSL.
+ * @return The next Ep0 Stage at PIL if PIL receive this setup packet.
+ *
+ */
+ virtual TControlStage EnquireEp0NextStage(const TUint8* aSetupBuf) const = 0;
+
+ /**
+ * This function gets called by PSL upon completion of a pending
+ * endpoint zero data transfer request.
+ *
+ * @param aRealEndpoint Either 0 for Ep0 OUT (= Read)
+ * or 1 for Ep0 IN (= Write).
+ * @param aCount The number of bytes received or transmitted.
+ * @param aError The error code of the completed transfer request.
+ * KErrNone if no error.
+ * KErrCancel if transfer was cancelled.
+ * KErrPrematureEnd if a premature end was encountered.
+ * @param aPktType The type of the packet that being completed.
+ *
+ * @return KErrNone if no error during transfer completion processing;
+ * KErrGeneral if request was a read & a Setup packet was received &
+ * the recipient for that packet couldn't be found (invalid packet: Ep0
+ * has been stalled); KErrNotFound if the request was a read & the
+ * recipient for that packet (Setup or data) _was_ * found - however no
+ * read had been set up by that recipient (this case should be used by
+ * PSL to disable Ep0 interrupt at that point and give the upper layer
+ * software time to set up a new Ep0 read; once the 'missing' read was
+ * set up either Ep0DataReceiveProceed or Ep0ReadSetupPktProceed of
+ * MPeripheralControllerIf class will be called by PIL).
+ */
+ virtual TInt Ep0RequestComplete(TInt aRealEndpoint,
+ TInt aCount,
+ TInt aError,
+ TControlPacketType aPktType) = 0;
+
+ /**
+ * PSL call this function upon completion of a pending data transfer
+ * request. This function isn't to be used for endpoint zero completions
+ * (use Ep0RequestComplete instead).
+ *
+ * @param aCallback A pointer to a data transfer request callback
+ * structure which was previously passed to PSL in a
+ * SetupEndpointWrite() or SetupEndpointRead() call.
+ *
+ */
+ virtual void EndpointRequestComplete(TUsbPeripheralRequest* aCallback) = 0;
+
+ /**
+ * This function gets called by PSL upon detection of either of the
+ * following events:
+ * - USB Reset,
+ * - USB Suspend event,
+ * - USB Resume signaling,
+ *
+ * When the Peripheral Controller PSL is part of an
+ * OTG-capable port, the PSL shall report the above events
+ * also when operating as the A-peripheral, including
+ * reporting the final suspend event that starts the HNP role
+ * switch back to A-host.
+ *
+ * In addition to the events above, a stand-alone peripheral
+ * controller PSL (one not associated with an OTG port) is
+ * required to report the following events:
+ * - VBUS rising above the session valid threshold
+ * - VBUS falling below the session valid threshold
+ *
+ * When the peripheral controller is part of an OTG port, the
+ * PIL layer receives VBUS notifications via the OTG stack,
+ * and the peripheral PSL is not expected to report them via
+ * this interface.
+ *
+ * When USB Battery Charging is supported on the
+ * peripheral-only port, there is a dependency between normal
+ * USB functionality and USB Battery Charging (see
+ * usb_charger_detection_shai.h and specifically the
+ * description of class MChargerDetectorIf). In this case it
+ * is the responsibility of the Peripheral Controller PSL to
+ * communicate with the Charger Detector PSL (which it may
+ * implement itself) with respect to VBUS events.
+ *
+ * When VBUS rises on the peripheral-only port that fully
+ * supports Battery Charging Specification Revision 1.1, the
+ * Charger Detector PSL and the Peripheral Controller PSL need
+ * to together guarantee that Data Contact Detect is completed
+ * and the port type detected before notifying VBUS rising.
+ * When the port type is known, the port type needs to be
+ * notified to the Charger Detector PSL Observer, followed by
+ * notifying a VBUS rising event to the Peripheral Controller
+ * PIL callback interface (via this function).
+ *
+ * Where Data Contact Detect is not supported, the VBUS rise
+ * event needs to be notified to the Peripheral Controller PIL
+ * callback interface (via this function) immediately and
+ * charger detection needs to proceed in parallel with the
+ * upper layers preparing the USB personality. This is
+ * necessary in order to ensure that we can fulfill the
+ * requirement to connect to the bus within a second, while
+ * still making as long as possible charger detection cycle to
+ * minimize the changes of false detections due to datalines
+ * not making contact yet.
+ *
+ * The Peripheral Controller PSL and the Charger Detector PSL
+ * need to together guarantee that the peripheral controller
+ * does not attempt to connect to the bus while charger
+ * detection is still on-going. When detection has been
+ * completed and upper layers have indicated readiness to
+ * connect to the bus (see MPeripheralControllerIf::PeripheralConnect(),
+ * the Peripheral Controller PSL must connect to the bus.
+ *
+ * @param aEvent An enum denoting the event that has occurred.
+ *
+ * @return KErrArgument if the event is not recognized, KErrNone
+ * otherwise
+ */
+ virtual TInt DeviceEventNotification(TUsbPeripheralEvent aEvent) = 0;
+
+ /**
+ * This function should be called by PSL once the peripheral
+ * controller (and thus the USB device) is in the Address state.
+ */
+ virtual void MoveToAddressState() = 0;
+
+ /**
+ * This function should be called by PSL after reception of an Ep0
+ * SET_FEATURE request with a feature selector of either {b_hnp_enable,
+ * a_hnp_support, a_alt_hnp_support}, but ONLY when that Setup packet is
+ * not handed up to PIL (for instance because it is auto-decoded and
+ * 'swallowed' by the peripheral controller hardware).
+ *
+ * @param aHnpState A bitmask indicating the present state of the three
+ * OTG feature selectors as follows:
+ *
+ * bit.0 == a_alt_hnp_support
+ * bit.1 == a_hnp_support
+ * bit.2 == b_hnp_enable
+ *
+ * @see TUsbHnpCaps
+ *
+ */
+ virtual void HandleHnpRequest(TInt aHnpState) = 0;
+
+ /**
+ * Returns the current USB device state.
+ *
+ * 'USB device state' here refers to the device states as defined
+ * in chapter 9 of the USB specification.
+ *
+ * @return The current USB device state, or EUsbPeripheralStateUndefined
+ * if peripheral stack is disabled.
+ *
+ */
+ virtual TUsbPeripheralState DeviceStatus() const = 0;
+
+ };
+
+ /**
+ * MPeripheralControllerIf
+ * @brief Abstract class for USB peripheral Chipset API.
+ * @version 0.2.
+ *
+ * PSL driver need to implement all those virtual functions in this class.
+ *
+ * Four Steps to create a vendor specific usb peripheral PDD.
+ *
+ * Step 1: Derive a new class from MUsbPeripheralControllerIf and
+ * implement all interfaces defined.
+ *
+ * Step 2: Create a new instance (we call it inst_of_psl) of the new class.
+ * Prepare the configuration data defined by structure
+ * TUsbPeripheralControllerProps (let's call it cfg_data )
+ *
+ * Step 3: Call UsbPeripheralPil::RegisterPeripheralController(inst_of_psl,cfg_data).
+ *
+ * Step 4: Member function SetPilCallbackInterface() will be called.
+ * An instance of MUsbPeripheralPilCallbackIf will be passed to
+ * PSL via this call. Record it since PSL need to reuse it later
+ * for any PIL functionality callback.
+ *
+ * That's all.
+ *
+ * dynamic view of PDD creation.
+ * PIL will be compiled and linked alone.
+ * PSL will be compiled alone and linked against a new lib named
+ * usbperipheralpil.lib.
+ *
+ * For PSL vendors, the following stuff are provided:
+ * usb_peripheral_shai.h & usb_peripheral_shai_shared.h which is
+ * used for PSL to implement against.
+ * usbperipheralpil.lib which is used for PSL to link against.
+ *
+ */
+ NONSHARABLE_CLASS(MPeripheralControllerIf)
+ {
+ public:
+ /**
+ * This function will be called once and only once by PIL when a PSL
+ * registered itself to PIL by calling
+ * UsbPeripheralPil::RegisterPeripheralController().
+ *
+ * PSL is expected to store the callback interface pointer so that make
+ * it possible to reporting events back to PIL layer.
+ *
+ * For stand-alone peripheral controllers (controllers not associated
+ * with an OTG port),the Peripheral Controller PSL is required to report
+ * a EUsbEventVbusRisen event by calling MUsbPeripheralPilCallbackIf::
+ * DeviceEventNotification() if VBUS is already high at the point this
+ * function is called.
+ *
+ * @param aPilCallbackIf A reference to PIL callback interface which
+ a PSL must use to report events.
+ */
+ virtual void SetPilCallbackInterface(MUsbPeripheralPilCallbackIf& aPilCallbackIf) = 0;
+
+ /**
+ * Sets endpoint zero's RX buffer.
+ * This buffer is maintains at PIL and always exists.
+ *
+ * @param aBuffer the buffer address
+ * @param aBufferLen the length of the buffer.
+ *
+ */
+ virtual void SetEp0RxBuffer(TUint8* aBuffer, TInt aBufferLen) = 0;
+
+ /**
+ * Determines the speed mode that this controller is operating at.
+ *
+ * @return one of the speed mode defined by TSpeed.
+ * @see TSpeed.
+ */
+ virtual TSpeed DeviceOperatingSpeed() = 0;
+
+ /**
+ * Forces the peripheral controller into a non-idle state to perform a
+ * USB remote wakeup operation.
+ *
+ * PIL layer will make sure the following preconditions are meet before
+ * calling this function:
+ * 1. we're already in suspended state for at least 5ms (Twtrsm).
+ * 2. remote wakeup had been enabled by host.
+ *
+ * @return KErrNone if successful, otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt SignalRemoteWakeup() = 0;
+
+ /**
+ * This function will be called by PIL upon decoding a SET_ADDRESS
+ * request. PIL will make sure that a status packet will be sent before
+ * calling this function as USB spec required if capability of
+ * KDevCapSetAddressAcceleration is not support by hardware; Otherwise
+ * SetAddress call will go ahead of status packet.
+ * @see KDevCapSetAddressAcceleration
+ *
+ * @param aAddress A valid USB device address that was received with the
+ * SET_ADDRESS request.
+ *
+ * @return KErrNone if address was set successfully or if controller's
+ * address cannot be set manually. otherwise one of the system-
+ * wide error codes.
+ */
+ virtual TInt SetDeviceAddress(TInt aAddress) = 0;
+
+ /**
+ * Configures (enables) an endpoint (incl. Ep0) for data transmission or
+ * reception.
+ *
+ * @param aRealEndpoint The number of the endpoint to be configured.
+ * @param aEndpointInfo A properly filled-in endpoint info structure.
+ *
+ * @return KErrNone if endpoint successfully configured; KErrArgument if
+ * endpoint number or endpoint info invalid; otherwise one of
+ * the system-wide error codes.
+ */
+ virtual TInt ConfigureEndpoint(TInt aRealEndpoint,
+ const TUsbPeripheralEndpointInfo& aEndpointInfo) = 0;
+
+ /**
+ * De-configures (disables) an endpoint (incl. Ep0).
+ *
+ * @param aRealEndpoint The number of the endpoint to be disabled.
+ *
+ * @return KErrNone if endpoint successfully de-configured; KErrArgument
+ * if endpoint number invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt DeConfigureEndpoint(TInt aRealEndpoint) = 0;
+
+ /**
+ * Queries the use of and endpoint resource.
+ *
+ * @param aRealEndpoint The number of the endpoint.
+ * @param aResource The endpoint resource to be queried.
+ * they are one of the following currently:
+ * KUsbEndpointInfoFeatureWord1_DMA.
+ * KUsbEndpointInfoFeatureWord1_DoubleBuffering.
+ *
+ * @return ETrue if the specified resource is in use at the endpoint,
+ * EFalse if not.
+ */
+ virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUint32 aResource) const = 0;
+
+ /**
+ * Sets up a read request on an endpoint (excl. Ep0) for data reception.
+ *
+ * PIL will construct a read request as aCallback, and use this function
+ * to setup and indicate the readiness for reading data from end point.
+ *
+ * PSL need to update related data member of aCallback and complete this
+ * request by calling EndpointRequestComplete() when request is done.
+ *
+ * @see TUsbPeripheralRequest
+ *
+ * @param aRealEndpoint The number of the endpoint to be used.
+ * @param aCallback A properly filled-in (by PIL) request callback.
+ *
+ * @return KErrNone if read successfully set up; KErrArgument if endpoint
+ * number is invalid. otherwise one of the system-wide error
+ * codes.
+ */
+ virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbPeripheralRequest& aCallback) = 0;
+
+ /**
+ * Sets up a write request on an endpoint (excl. Ep0) for transmission.
+ *
+ * PIL will contruct a write request as aCallback, and use this function
+ * to pass down it to PSL.
+ *
+ * PSL need to update related data member of aCallback and complete this
+ * request by calling EndpointRequestComplete() when data is transmitted
+ * or any error found.
+ * @see TUsbPeripheralRequest
+ *
+ * @param aRealEndpoint The number of the endpoint to be used.
+ * @param aCallback A properly filled-in request callback.
+ *
+ * @return KErrNone if write successfully set up; KErrArgument if
+ * endpoint number is invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbPeripheralRequest& aCallback) = 0;
+
+ /**
+ * Cancels a read request on an endpoint (excl. Ep0).
+ *
+ * Note that endpoint 0 read requests are never cancelled by PIL, so
+ * there is also no CancelEndpointZeroRead() function.
+ *
+ * @param aRealEndpoint The number of the endpoint to be used.
+ *
+ * @return KErrNone if read successfully cancelled; KErrArgument if
+ * endpoint number is invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt CancelEndpointRead(TInt aRealEndpoint) = 0;
+
+ /**
+ * Cancels a write request on an endpoint (incl. Ep0).
+ *
+ * PIL calls this function also to cancel endpoint zero write requests.
+ *
+ * @param aRealEndpoint The number of the endpoint to be used.
+ *
+ * @return KErrNone if write successfully cancelled; KErrArgument if
+ * endpoint number is invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt CancelEndpointWrite(TInt aRealEndpoint) = 0;
+
+ /**
+ * Same as SetupEndpointRead(), but for endpoint zero only.
+ *
+ * No callback structure is used here as reading to ep0 (host may at any
+ * time send a SETUP packet) must be ready even before upper application
+ * is ready. So, a buffer will be passed down to PSL by
+ * MPeripheralControllerIf::SetEp0RxBuffer() during PIL construction,
+ * this will benefits the PSL to have a buffer always available for this
+ * purpose.
+ *
+ * PSL must complete this request by EndpointRequestComplete()
+ *
+ * @return KErrNone if read successfully set up; otherwise one of the
+ * system-wide error codes.
+ */
+ virtual TInt SetupEndpointZeroRead() = 0;
+
+ /**
+ * Same as SetupEndpointWrite(), but for endpoint zero only.
+ *
+ * No callback is used here as this function is only used by
+ * PIL layer only and no user side request exists for it.
+ *
+ * @param aBuffer This points to the beginning of the data to be sent.
+ * @param aLength The number of bytes to be sent.
+ * @param aZlpReqd ETrue if a ZLP is must be sent after the data.
+ *
+ * PSL must complete this request by EndpointRequestComplete()
+ *
+ * @return KErrNone if write successfully set up; otherwise one of the
+ * system-wide error codes.
+ */
+ virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer,
+ TInt aLength,
+ TBool aZlpReqd = EFalse) = 0;
+
+ /**
+ * Sets up on Ep0 for the transmission of a single zero-length packet.
+ *
+ * @return KErrNone if ZLP successfully set up; otherwise one of the
+ * system-wide error codes.
+ */
+ virtual TInt SendEp0ZeroByteStatusPacket() = 0;
+
+ /**
+ * Stalls an endpoint (incl. Ep0).
+ *
+ * Not applicable to Isochronous endpoints.
+ *
+ * @param aRealEndpoint The number of the endpoint to be stalled.
+ *
+ * @return KErrNone if endpoint successfully stalled; KErrArgument if
+ * endpoint number is invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt StallEndpoint(TInt aRealEndpoint) = 0;
+
+ /**
+ * Clears the stall condition on an endpoint (incl. Ep0).
+ *
+ * Not applicable to Isochronous endpoints.
+ *
+ * @param aRealEndpoint The number of the endpoint to be stalled.
+ *
+ * @return KErrNone if endpoint successfully de-stalled; KErrArgument if
+ * endpoint number invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt ClearStallEndpoint(TInt aRealEndpoint) = 0;
+
+ /**
+ * Resets the data toggle bit for an endpoint (incl. Ep0).
+ *
+ * Isochronous endpoints don't use data toggles.
+ *
+ * @param aRealEndpoint The number of the endpoint to be used.
+ *
+ * @return KErrNone if data toggle successfully reset; KErrArgument if
+ * endpoint number invalid; otherwise one of the system-wide
+ * error codes.
+ */
+ virtual TInt ResetDataToggle(TInt aRealEndpoint) = 0;
+
+ /**
+ * Returns the frame number of the last received SOF packet.
+ *
+ * @return The (11-bit) frame number of the last received SOF packet.
+ *
+ */
+ virtual TInt SynchFrameNumber() const = 0;
+
+ /**
+ * Stores the (11-bit) frame number that should be sent in response to
+ * the next SYNCH_FRAME request(s).
+ *
+ * @param aFrameNumber The (11-bit) frame number to be set
+ */
+ virtual void SetSynchFrameNumber(TInt aFrameNumber) = 0;
+
+ /**
+ * Starts peripheral controller.
+ *
+ * This initializes the device controller hardware before any other
+ * operation can be performed.
+ * Tasks to be carried out here might include:
+ * - resetting the whole peripheral controller design
+ * - enabling the peripheral controller's clock
+ * - binding & enabling the peripheral controller (primary) interrupt
+ * - write meaningful values to some general controller registers
+ * - enabling the USB Reset interrupt
+ * - enabling the peripheral controller proper (for instance by
+ * setting an Enable bit).
+ *
+ * This function is also used in an OTG environment when the
+ * peripheral stack becomes enabled and the controller needs
+ * to be started and enabled for peripheral use. If the HW
+ * platform shares resources such as clocks and power between
+ * the host and peripheral HW, it is probably easiest for the
+ * PSL to handle the role switch based on the
+ * MOtgControllerIf::SetControllerRole() call to the OTG
+ * Controller interface.
+ *
+ * @return KErrNone if the controller was successfully started;
+ * otherwise one of the system-wide error codes.
+ *
+ * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
+ */
+ virtual TInt StartPeripheralController() = 0;
+
+ /**
+ * Stops the peripheral controller.
+ *
+ * This basically makes undone what happened in StartPeripheralController().
+ * Tasks to be carried out here might include:
+ * - disabling peripheral controller proper.
+ * - disabling the USB Reset interrupt.
+ * - disabling & unbinding the peripheral controller (primary) interrupt.
+ * - disabling the peripheral controller's clock.
+ *
+ * This function is also used in an OTG environment when the peripheral
+ * stack becomes disabled and the peripheral hardware resources can be
+ * released. If the hardware platform shares resources such as clocks
+ * and power between the host and peripheral hardware, it is probably
+ * easiest for the PSL to handle the role switch based on the
+ * MOtgControllerIf::SetControllerRole() call to the OTG Controller
+ * interface.
+ *
+ * @return KErrNone if peripheral controller successfully stopped;
+ * otherwise one of the system-wide error codes.
+ *
+ * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
+ */
+ virtual TInt StopPeripheralController() = 0;
+
+ /**
+ * This function is used to indicate that upper layers are ready to
+ * start operating as peripheral and want to connect to the USB bus
+ * if possible.
+ *
+ * Since this functionality is not part of the USB specification it
+ * has to be explicitly supported, either by the peripheral controller
+ * itself or by the hardware platform.
+ *
+ * This call merely reports the upper layer readiness to connect, and
+ * it is the responsiblity of the PSL to assess when all prerequisites
+ * for connection are satisfied and physically connect when they are.
+ * These prerequisites include:
+ *
+ * 1. Upper layer readiness has been indicated by calling
+ * PeripheralConnect().
+ *
+ * 2. The peripheral controller has been started and enabled
+ * by StartPeripheralController().
+ *
+ * The connection readiness assessment responsibility is delegated to the
+ * PSL because the physical connection may sometimes be handled by a HW
+ * state machine, thus making the correct SW-controlled connection time
+ * HW-specific.
+ *
+ * @return KErrNone if peripheral controller successfully connected;
+ * otherwise one of the system-wide error codes.
+ */
+ virtual TInt PeripheralConnect() = 0;
+
+ /**
+ * Called to indicate that upper layers no longer want to operate as the
+ * peripheral and we must disconnect from the USB bus.
+ *
+ * Since this functionality is not part of the USB specification it
+ * has to be explicitly supported, either by the peripheral controller
+ * itself or by the hardware platform.
+ *
+ * @return KErrNone if controller is successfully disconnected;
+ * otherwise one of the system-wide error codes.
+ */
+ virtual TInt PeripheralDisconnect() = 0;
+
+ /**
+ * Implements anything peripheral controller might required by following
+ * bus resume signal.
+ *
+ * This function gets called by PIL after it has been notified (by
+ * PSL) about the Suspend condition.
+ */
+ virtual void Suspend() = 0;
+
+ /**
+ * Implements anything peripheral controller might required by following
+ * bus resume signal.
+ *
+ * This function gets called by PIL after it has been notified (by
+ * PSL) about the Resume event.
+ */
+ virtual void Resume() = 0;
+
+ /**
+ * Implements anything peripheral controller might required by following
+ * bus resume signal.
+ *
+ * This function gets called by PIL after it has been notified (by
+ * PSL) about the Reset event.
+ */
+ virtual void Reset() = 0;
+
+ /**
+ * PIL call this function to signal PSL that it has finished processing
+ * a received Setup packet (on Ep0) and that PSL can now prepare
+ * itself for the next Ep0 reception.
+ *
+ * The reason for having this function is that the situation where no
+ * Ep0 read has been set up by user and thus a received Setup packet
+ * cannot immediately be delivered to user. Once user however
+ * sets up an Ep0 read, PIL then completes the request and eventually
+ * calls this function. We can implement some sort of flow-control by
+ * this way.
+ */
+ virtual void Ep0ReadSetupPktProceed() = 0;
+
+ /**
+ * PIL call this function to signal PSL that it has finished processing
+ * a received Ep0 data packet and that PSL can now prepare itself for
+ * the next Ep0 reception.
+ *
+ * The reason for having this function is that the situation where no
+ * Ep0 read has been set up by user and thus a received Setup packet
+ * cannot immediately be delivered to user. Once user however
+ * sets up an Ep0 read, PIL then completes the request and eventually
+ * calls this function. We can implement some sort of flow-control by
+ * this way.
+ */
+ virtual void Ep0ReadDataPktProceed() = 0;
+
+ /**
+ * Puts controller into a specific test mode (during HS operation only).
+ *
+ * 9.4.9 Set Feature: "The transition to test mode must be complete no
+ * later than 3 ms after the completion of the status stage of the
+ * request." (The status stage will have been completed immediately
+ * before this function gets called.)
+ *
+ * @param aTestSelector The specific test mode selector.
+ *
+ * @return KErrNone if the specified test mode was entered successfully;
+ * otherwise one of the system-wide error codes.
+ */
+ virtual TInt EnterTestMode(TUsbTestModeSelector aTestSelector) = 0;
+ };
+
+
+ /**
+ * This static class provides the interface which PSL implementation shall
+ * use to register itself to PIL layer.
+ */
+ NONSHARABLE_CLASS(UsbPeripheralPil)
+ {
+ public:
+ /**
+ * Registration function to be used by a stand-alone (non-OTG
+ * port) Peripheral Controller PSL to register itself to the
+ * PIL layer. Peripheral Controllers that are part of an
+ * OTG-port are registered by the OTG Controller PSL (see
+ * usb_otg_shai.h, function UsbOtgPil::RegisterOtgController).
+ *
+ * The intended usage is that each stand-alone Peripheral
+ * Controller PSL is a kernel extension that registers itself
+ * to the USB Peripheral PIL layer by making this call from
+ * their own kernel extension entry point function (or an
+ * equivalent code that runs during bootup).
+ *
+ * When the PSL makes this call, PIL layer will call
+ * SetPilCallbackInterface() function of the supplied Peripheral
+ * Controller interface to supply the PSL a reference to PIL
+ * callback interface to be used for reporting peripheral events.
+ *
+ * @param aPeripheralControllerIf Reference to the Peripheral
+ * Controller interface implemented by the registering PSL.
+ *
+ * @param aProperties Reference to an object describing the
+ * static properties of the Peripheral Controller. PIL
+ * layer requires that the supplied reference remains valid
+ * indefinitely, as a Peripheral Controller cannot unregister.
+ *
+ * @lib usbperipheralpil.lib
+ */
+ IMPORT_C static void RegisterPeripheralController(MPeripheralControllerIf& aPeripheralControllerIf,
+ const TPeripheralControllerProperties& aProperties );
+
+ private:
+ /**
+ * No instance of this class need to be created
+ */
+ UsbPeripheralPil();
+ };
+ };
+
+#include <usb/usb_peripheral_shai.inl>
+
+#endif // USB_PERIPHERAL_SHAI_H
+
+// End of File