sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // e32/include/drivers/usbcdesc.h
sl@0: // USB descriptors and their management.
sl@0: // 
sl@0: //
sl@0: 
sl@0: /**
sl@0:  @file usbcdesc.h
sl@0:  @internalTechnology
sl@0: */
sl@0: 
sl@0: #ifndef __USBCDESC_H__
sl@0: #define __USBCDESC_H__
sl@0: 
sl@0: #include <kernel/kernel.h>
sl@0: 
sl@0: 
sl@0: // Hard-wired positions of some descriptors in iDescriptors array (whether present or not):
sl@0: static const TInt KDescPosition_Device           = 0;
sl@0: static const TInt KDescPosition_DeviceQualifier  = 1;
sl@0: static const TInt KDescPosition_OtherSpeedConfig = 2;
sl@0: static const TInt KDescPosition_Config           = 3;
sl@0: static const TInt KDescPosition_Otg              = 4;
sl@0: static const TInt KDescPosition_FirstAvailable   = 5;
sl@0: 
sl@0: // Hard-wired positions of string descriptors in iStrings array (whether present or not):
sl@0: static const TInt KStringPosition_Langid           = 0;
sl@0: static const TInt KStringPosition_Manufact         = 1;
sl@0: static const TInt KStringPosition_Product          = 2;
sl@0: static const TInt KStringPosition_Serial           = 3;
sl@0: static const TInt KStringPosition_Config           = 4;
sl@0: static const TInt KStringPosition_OtherSpeedConfig = 5;
sl@0: static const TInt KStringPosition_FirstAvailable   = 6;
sl@0: 
sl@0: 
sl@0: class TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual ~TUsbcDescriptorBase();
sl@0: 	void SetByte(TInt aPosition, TUint8 aValue);
sl@0: 	void SetWord(TInt aPosition, TUint16 aValue);
sl@0: 	TUint8 Byte(TInt aPosition) const;
sl@0: 	TUint16 Word(TInt aPosition) const;
sl@0: 	void GetDescriptorData(TDes8& aBuffer) const;
sl@0: 	TInt GetDescriptorData(TUint8* aBuffer) const;
sl@0: 	TInt GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const;
sl@0: 	const TDes8& DescriptorData() const;
sl@0: 	TDes8& DescriptorData();
sl@0: 	TUint Size() const;
sl@0: 	TUint8 Type() const;
sl@0: 	virtual void UpdateFs();
sl@0: 	virtual void UpdateHs();
sl@0: protected:
sl@0: 	TUsbcDescriptorBase();
sl@0: 	void SetBufferPointer(const TDesC8& aDes);
sl@0: private:
sl@0: #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
sl@0: 	TUint8 iIndex;											// only needed for SET_DESCRIPTOR
sl@0: #endif
sl@0: 	TPtr8 iBufPtr;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcDeviceDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	/** aMaxPacketSize0 should be the Ep0 max packet size for FS operation (as the HS size
sl@0: 		is fixed and known).
sl@0: 	*/
sl@0: 	static TUsbcDeviceDescriptor* New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
sl@0: 									  TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
sl@0: 									  TUint16 aVendorId, TUint16 aProductId,
sl@0: 									  TUint16 aDeviceRelease, TUint8 aNumConfigurations);
sl@0: 	virtual void UpdateFs();
sl@0: 	virtual void UpdateHs();
sl@0: private:
sl@0: 	TUsbcDeviceDescriptor();
sl@0: 	TInt Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
sl@0: 				   TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
sl@0: 				   TUint16 aDeviceRelease, TUint8 aNumConfigurations);
sl@0: 	TBuf8<KUsbDescSize_Device> iBuf;
sl@0: 	TUint8 iEp0Size_Fs;										// holds Ep0 size for FS (could be < 64)
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcDeviceQualifierDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	/** aMaxPacketSize0 should be the Ep0 max packet size for FS operation (as the HS size
sl@0: 		is fixed and known).
sl@0: 	*/
sl@0: 	static TUsbcDeviceQualifierDescriptor* New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
sl@0: 											   TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
sl@0: 											   TUint8 aNumConfigurations, TUint8 aReserved=0);
sl@0: 	virtual void UpdateFs();
sl@0: 	virtual void UpdateHs();
sl@0: private:
sl@0: 	TUsbcDeviceQualifierDescriptor();
sl@0: 	TInt Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
sl@0: 				   TUint8 aMaxPacketSize0, TUint8 aNumConfigurations, TUint8 aReserved);
sl@0: 	TBuf8<KUsbDescSize_DeviceQualifier> iBuf;
sl@0: 	TUint8 iEp0Size_Fs;										// holds Ep0 size for FS (could be < 64)
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcConfigDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	/** aMaxPower should be given here in milliamps (not mA/2). */
sl@0: 	static TUsbcConfigDescriptor* New(TUint8 aConfigurationValue, TBool aSelfPowered, TBool aRemoteWakeup,
sl@0: 									  TUint16 aMaxPower);
sl@0: private:
sl@0: 	TUsbcConfigDescriptor();
sl@0: 	TInt Construct(TUint8 aConfigurationValue, TBool aSelfPowered, TBool aRemoteWakeup, TUint16 aMaxPower);
sl@0: 	TBuf8<KUsbDescSize_Config> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: // The Other_Speed_Configuration descriptor has same size and layout as the
sl@0: // standard Configuration descriptor, therefore we don't need a new definition.
sl@0: typedef TUsbcConfigDescriptor TUsbcOtherSpeedConfigDescriptor;
sl@0: 
sl@0: 
sl@0: class TUsbcInterfaceDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	static TUsbcInterfaceDescriptor* New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, TInt NumEndpoints,
sl@0: 										 const TUsbcClassInfo& aClassInfo);
sl@0: private:
sl@0: 	TUsbcInterfaceDescriptor();
sl@0: 	TInt Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, TInt aNumEndpoints,
sl@0: 				   const TUsbcClassInfo& aClassInfo);
sl@0: 	TBuf8<KUsbDescSize_Interface> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcEndpointDescriptorBase : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual void UpdateFs();
sl@0: 	virtual void UpdateHs();
sl@0: protected:
sl@0: 	TInt Construct(const TUsbcEndpointInfo& aEpInfo);
sl@0: 	TUsbcEndpointDescriptorBase();
sl@0: protected:
sl@0: 	/** Stores the endpoint size to be used for FS. */
sl@0: 	TInt iEpSize_Fs;
sl@0: 	/** Stores the endpoint size to be used for HS. */
sl@0: 	TInt iEpSize_Hs;
sl@0: 	/** Stores the endpoint polling interval to be used for FS. */
sl@0: 	TInt iInterval_Fs;
sl@0: 	/** Stores the endpoint polling interval to be used for HS. */
sl@0: 	TInt iInterval_Hs;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcEndpointDescriptor : public TUsbcEndpointDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	static TUsbcEndpointDescriptor* New(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo);
sl@0: private:
sl@0: 	TUsbcEndpointDescriptor();
sl@0: 	TInt Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo);
sl@0: 	TBuf8<KUsbDescSize_Endpoint> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcAudioEndpointDescriptor : public TUsbcEndpointDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	static TUsbcAudioEndpointDescriptor* New(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo);
sl@0: private:
sl@0: 	TUsbcAudioEndpointDescriptor();
sl@0: 	TInt Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo);
sl@0: 	TBuf8<KUsbDescSize_AudioEndpoint> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcOtgDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	static TUsbcOtgDescriptor* New(TBool aHnpSupport, TBool aSrpSupport);
sl@0: private:
sl@0: 	TUsbcOtgDescriptor();
sl@0: 	TInt Construct(TBool aHnpSupport, TBool aSrpSupport);
sl@0: 	TBuf8<KUsbDescSize_Otg> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcClassSpecificDescriptor : public TUsbcDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual ~TUsbcClassSpecificDescriptor();
sl@0: 	static TUsbcClassSpecificDescriptor* New(TUint8 aType, TInt aSize);
sl@0: private:
sl@0: 	TUsbcClassSpecificDescriptor();
sl@0: 	TInt Construct(TUint8 aType, TInt aSize);
sl@0: 	HBuf8* iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcStringDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual ~TUsbcStringDescriptorBase();
sl@0: 	TUint16 Word(TInt aPosition) const;
sl@0: 	void SetWord(TInt aPosition, TUint16 aValue);
sl@0: 	TInt GetDescriptorData(TUint8* aBuffer) const;
sl@0: 	TInt GetDescriptorData(TUint8* aBuffer, TUint aMaxSize) const;
sl@0: 	const TDes8& StringData() const;
sl@0: 	TDes8& StringData();
sl@0: 	TUint Size() const;
sl@0: 	void SetBufferPointer(const TDesC8& aDes);
sl@0: protected:
sl@0: 	TUsbcStringDescriptorBase();
sl@0: 	TBuf8<2> iSBuf;
sl@0: 	TPtr8 iBufPtr;
sl@0: private:
sl@0: //	TUint8 iIndex;											// not needed in DescriptorPool: position == index
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcStringDescriptor : public TUsbcStringDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual ~TUsbcStringDescriptor();
sl@0: 	static TUsbcStringDescriptor* New(const TDesC8& aString);
sl@0: private:
sl@0: 	TUsbcStringDescriptor();
sl@0: 	TInt Construct(const TDesC8& aString);
sl@0: 	HBuf8* iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: // Currently we support only one language, and thus there's no need to provide
sl@0: // a LangId string descriptor with more than one array element.
sl@0: class TUsbcLangIdDescriptor : public TUsbcStringDescriptorBase
sl@0: 	{
sl@0: public:
sl@0: 	virtual ~TUsbcLangIdDescriptor();
sl@0: 	static TUsbcLangIdDescriptor* New(TUint16 aLangId);
sl@0: private:
sl@0: 	TUsbcLangIdDescriptor();
sl@0: 	TInt Construct(TUint16 aLangId);
sl@0: 	TBuf8<2> iBuf;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: class TUsbcDescriptorPool
sl@0: 	{
sl@0: public:
sl@0: 	TUsbcDescriptorPool(TUint8* aEp0_TxBuf);
sl@0: 	~TUsbcDescriptorPool();
sl@0: 	TInt Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
sl@0: 			  TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
sl@0: 			  TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
sl@0: 			  TUsbcStringDescriptor* aConfig, TUsbcOtgDescriptor* aOtgDesc);
sl@0: 	TInt InitHs();
sl@0: 	TInt UpdateDescriptorsFs();
sl@0: 	TInt UpdateDescriptorsHs();
sl@0: 
sl@0: 	// Descriptors
sl@0: 	TInt FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const;
sl@0: 	void InsertDescriptor(TUsbcDescriptorBase* aDesc);
sl@0: 	void DeleteIfcDescriptor(TInt aNumber, TInt aSetting=0);
sl@0: 	// The TC in many of the following functions stands for 'ThreadCopy' because that's what happens there.
sl@0: 	TInt GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const;
sl@0: 	TInt SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer);
sl@0: 	TInt GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const;
sl@0: 	TInt SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer);
sl@0:     TInt GetOtgDescriptorTC(DThread* aThread, TDes8& aBuffer) const;
sl@0: 	TInt SetOtgDescriptor(const TDesC8& aBuffer);
sl@0: 	TInt GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, TInt aSetting) const;
sl@0: 	TInt SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting);
sl@0: 	TInt GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, TInt aSetting,
sl@0: 								 TUint8 aEndpointAddress) const;
sl@0: 	TInt SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface, TInt aSetting,
sl@0: 								 TUint8 aEndpointAddress);
sl@0: 	TInt GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress, TInt& aSize) const;
sl@0: 	TInt GetDeviceQualifierDescriptorTC(DThread* aThread, TDes8& aBuffer) const;
sl@0: 	TInt SetDeviceQualifierDescriptorTC(DThread* aThread, const TDes8& aBuffer);
sl@0: 	TInt GetOtherSpeedConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const;
sl@0: 	TInt SetOtherSpeedConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer);
sl@0: 	TInt GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, TInt aSetting) const;
sl@0: 	TInt SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface, TInt aSetting,
sl@0: 									TInt aSize);
sl@0: 	TInt GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const;
sl@0: 	TInt GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, TInt aSetting,
sl@0: 								   TUint8 aEndpointAddress) const;
sl@0: 	TInt SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface, TInt aSetting,
sl@0: 								   TUint8 aEndpointAddress, TInt aSize);
sl@0: 	TInt GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress, TInt& aSize) const;
sl@0: 
sl@0: 	// String descriptors
sl@0: 	void SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting=0);
sl@0: 	TInt GetStringDescriptorLangIdTC(DThread* aThread, TDes8& aLangId) const;
sl@0: 	TInt SetStringDescriptorLangId(TUint16 aLangId);
sl@0: 	TInt GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const;
sl@0: 	TInt SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString);
sl@0: 	TInt RemoveManufacturerStringDescriptor();
sl@0: 	TInt GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const;
sl@0: 	TInt SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString);
sl@0: 	TInt RemoveProductStringDescriptor();
sl@0: 	TInt GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const;
sl@0: 	TInt SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString);
sl@0: 	TInt RemoveSerialNumberStringDescriptor();
sl@0: 	TInt GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const;
sl@0: 	TInt SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString);
sl@0: 	TInt RemoveConfigurationStringDescriptor();
sl@0: 	TInt GetStringDescriptorTC(DThread* aThread, TInt aIndex, TDes8& aString) const;
sl@0: 	TInt SetStringDescriptorTC(DThread* aThread, TInt aIndex, const TDes8& aString);
sl@0: 	TInt RemoveStringDescriptor(TInt aIndex);
sl@0: 
sl@0: private:
sl@0: 	// Descriptors
sl@0: 	void InsertIfcDesc(TUsbcDescriptorBase* aDesc);
sl@0: 	void InsertEpDesc(TUsbcDescriptorBase* aDesc);
sl@0: 	TInt FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const;
sl@0: 	TInt FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const;
sl@0: 	void DeleteDescriptors(TInt aIndex, TInt aCount = 1);
sl@0: 	void UpdateConfigDescriptorLength(TInt aLength);
sl@0: 	void UpdateConfigDescriptorNumIfcs(TInt aNumber);
sl@0: 	void UpdateIfcNumbers(TInt aNumber);
sl@0: 	TInt GetDeviceDescriptor(TInt aIndex) const;
sl@0: 	TInt GetConfigurationDescriptor(TInt aIndex) const;
sl@0: 	TInt GetOtgDescriptor() const;
sl@0: 
sl@0: 	// String descriptors
sl@0: 	TInt GetStringDescriptor(TInt aIndex) const;
sl@0: 	TInt GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, TInt aIndex, TInt aPosition) const;
sl@0: 	TInt SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, TInt aIndex, TInt aPosition);
sl@0: 	TInt RemoveDeviceStringDescriptor(TInt aIndex, TInt aPosition);
sl@0: 	void ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc);
sl@0: 	TBool AnyStringDescriptors() const;
sl@0: 	TBool StringDescriptorExists(TInt aIndex) const;
sl@0: 	TInt FindAvailableStringPos() const;
sl@0: 
sl@0: private:
sl@0: 	// Data members
sl@0: 	RPointerArray<TUsbcDescriptorBase> iDescriptors;
sl@0: 	RPointerArray<TUsbcStringDescriptorBase> iStrings;
sl@0: 	TInt iIfcIdx;
sl@0: 	TUint8* const iEp0_TxBuf;								// points to the controller's ep0 TX buffer
sl@0: 	TBool iHighSpeed;										// true if currently operating at high-speed
sl@0: 	};
sl@0: 
sl@0: 
sl@0: #endif	// __USBCDESC_H__