os/kernelhwsrv/kerneltest/e32test/iic/iic_psl/i2c.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test/iic/iic_psl/I2c.cpp
    15 //
    16 
    17 #include "i2c.h"
    18 
    19 #ifdef IIC_INSTRUMENTATION_MACRO
    20 #include <drivers/iic_trace.h>
    21 #endif
    22 
    23 
    24 #if defined(MASTER_MODE) && !defined(SLAVE_MODE)
    25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::EMaster};
    26 #elif defined(MASTER_MODE) && defined(SLAVE_MODE)
    27 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMasterSlave};
    28 #else
    29 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::ESlave, DIicBusChannel::ESlave, DIicBusChannel::ESlave};
    30 #endif
    31 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
    32 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
    33 
    34 #ifdef STANDALONE_CHANNEL
    35 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
    36 #else
    37 _LIT(KPddNameI2c,"i2c.pdd");
    38 #endif
    39 
    40 #ifndef STANDALONE_CHANNEL
    41 LOCAL_C TInt8 AssignChanNum()
    42 	{
    43 	static TInt8 iBaseChanNum = KI2cChannelNumBase;
    44 	I2C_PRINT(("I2C AssignChanNum - on entry, iBaseChanNum = 0x%x\n",iBaseChanNum));
    45 	return iBaseChanNum++; // Arbitrary, for illustration
    46 	}
    47 #endif/*STANDALONE_CHANNEL*/
    48 
    49 #ifdef SLAVE_MODE
    50 LOCAL_C TInt16 AssignSlaveChanId()
    51 	{
    52 	static TInt16 iBaseSlaveChanId = KI2cSlaveChannelIdBase;
    53 	I2C_PRINT(("I2C AssignSlaveChanId - on entry, iBaseSlaveChanId = 0x%x\n",iBaseSlaveChanId));
    54 	return iBaseSlaveChanId++; // Arbitrary, for illustration
    55 	}
    56 #endif/*SLAVE_MODE*/
    57 
    58 NONSHARABLE_CLASS(DSimulatedI2cDevice) : public DPhysicalDevice
    59 	{
    60 // Class to faciliate loading of the IIC classes
    61 public:
    62 	class TCaps
    63 		{
    64 	public:
    65 		TVersion iVersion;
    66 		};
    67 public:
    68 	DSimulatedI2cDevice();
    69 	virtual TInt Install();
    70 	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    71 	virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    72 	virtual void GetCaps(TDes8& aDes) const;
    73 	inline static TVersion VersionRequired();
    74 	};
    75 
    76 TVersion DSimulatedI2cDevice::VersionRequired()
    77 	{
    78 	I2C_PRINT(("DSimulatedI2cDevice::VersionRequired\n"));
    79 	return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber);
    80 	}
    81 
    82 /** Factory class constructor */
    83 DSimulatedI2cDevice::DSimulatedI2cDevice()
    84 	{
    85 	I2C_PRINT(("DSimulatedI2cDevice::DSimulatedI2cDevice\n"));
    86     iVersion = DSimulatedI2cDevice::VersionRequired();
    87 	}
    88 
    89 TInt DSimulatedI2cDevice::Install()
    90     {
    91 	I2C_PRINT(("DSimulatedI2cDevice::Install\n"));
    92     return(SetName(&KPddNameI2c));
    93     }
    94 
    95 /**  Called by the kernel's device driver framework to create a Physical Channel. */
    96 TInt DSimulatedI2cDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
    97     {
    98 	I2C_PRINT(("DSimulatedI2cDevice::Create\n"));
    99     return KErrNone;
   100     }
   101 
   102 /**  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
   103 TInt DSimulatedI2cDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
   104     {
   105 	I2C_PRINT(("DSimulatedI2cDevice::Validate\n"));
   106    	if (!Kern::QueryVersionSupported(DSimulatedI2cDevice::VersionRequired(),aVer))
   107 		return(KErrNotSupported);
   108     return KErrNone;
   109     }
   110 
   111 /** Return the driver capabilities */
   112 void DSimulatedI2cDevice::GetCaps(TDes8& aDes) const
   113     {
   114 	I2C_PRINT(("DSimulatedI2cDevice::GetCaps\n"));
   115 	// Create a capabilities object
   116 	TCaps caps;
   117 	caps.iVersion = iVersion;
   118 	// Zero the buffer
   119 	TInt maxLen = aDes.MaxLength();
   120 	aDes.FillZ(maxLen);
   121 	// Copy capabilities
   122 	TInt size=sizeof(caps);
   123 	if(size>maxLen)
   124 	   size=maxLen;
   125 	aDes.Copy((TUint8*)&caps,size);
   126     }
   127 
   128 // supported channels for this implementation
   129 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
   130 
   131 
   132 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
   133 DECLARE_STANDARD_PDD()		// I2c test driver to be explicitly loaded as an LDD, not kernel extension
   134 	{	
   135 #ifndef STANDALONE_CHANNEL
   136 	DIicBusChannel* chan=NULL;
   137 	for(TInt i=0; i<NUM_CHANNELS; i++)
   138 		{
   139 	I2C_PRINT(("\n"));
   140 #if defined(MASTER_MODE)
   141 		if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster))
   142 			{
   143 			chan=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
   144 			if(!chan)
   145 				return NULL;
   146 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
   147 			if(((DSimulatedIicBusChannelMasterI2c*)chan)->Create()!=KErrNone)
   148 			    {
   149 			    delete chan;
   150 				return NULL;
   151                 }
   152 			}
   153 #endif
   154 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
   155 		if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave)
   156 			{
   157 			DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
   158 			if(!chanM)
   159 				return NULL;
   160 			DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
   161 			if(!chanS)
   162 			    {
   163 			    delete chanM;
   164 				return NULL;
   165 			    }
   166 			// For MasterSlave channel, the channel number for both the Master and Slave channels must be the same
   167 			TInt8 msChanNum = ((DSimulatedIicBusChannelMasterI2c*)chanM)->GetChanNum();
   168 			((DSimulatedIicBusChannelSlaveI2c*)chanS)->SetChanNum(msChanNum);
   169 
   170 			chan=new DSimulatedIicBusChannelMasterSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i),(DSimulatedIicBusChannelMasterI2c*)chanM,(DSimulatedIicBusChannelSlaveI2c*)chanS); // Generic implementation
   171 			if(!chan)
   172 			    {
   173 			    delete chanM;
   174 			    delete chanS;
   175 				return NULL;
   176 			    }
   177 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
   178 			if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone)
   179 			    {
   180 			    delete chanM;
   181 			    delete chanS;
   182 			    delete chan;
   183 				return NULL;
   184 			    }
   185 			}
   186 #endif
   187 #if defined(SLAVE_MODE)
   188 		if(CHANNEL_TYPE(i) == (DIicBusChannel::ESlave))
   189 			{
   190 			chan=new DSimulatedIicBusChannelSlaveI2c(BUS_TYPE,CHANNEL_DUPLEX(i));
   191 			if(!chan)
   192 				return NULL;
   193 			I2C_PRINT(("I2C chan created at 0x%x\n",chan));
   194 			if(((DSimulatedIicBusChannelSlaveI2c*)chan)->Create()!=KErrNone)
   195 			    {
   196 			    delete chan;
   197 			    return NULL;
   198 			    }
   199 			}
   200 #endif
   201 #if !defined(MASTER_MODE) && !defined(SLAVE_MODE)
   202 #error I2C mode not defined as Master, Slave nor Master-Slave
   203 #endif
   204 		if(chan == NULL)
   205 			{
   206 			I2C_PRINT(("\n\nI2C: Channel of type (%d) not created for index %d\n\n",CHANNEL_TYPE(i),i));
   207 			return NULL;
   208 			}
   209 		ChannelPtrArray[i]=chan;
   210 		}
   211 	I2C_PRINT(("\nI2C PDD, channel creation loop done- about to invoke RegisterChannels\n\n"));
   212 #ifdef IIC_INSTRUMENTATION_MACRO
   213 	IIC_REGISTERCHANS_START_PSL_TRACE;
   214 #endif
   215 
   216 	TInt r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS);
   217 
   218 #ifdef IIC_INSTRUMENTATION_MACRO
   219 	IIC_REGISTERCHANS_END_PSL_TRACE;
   220 #endif
   221 	I2C_PRINT(("\nI2C - returned from RegisterChannels with r=%d\n",r));
   222 	if(r!=KErrNone)
   223 		{
   224 		delete chan;
   225 		return NULL;
   226 		}
   227 #endif
   228 	return new DSimulatedI2cDevice;
   229 	}
   230 
   231 
   232 #ifdef MASTER_MODE
   233 #ifdef STANDALONE_CHANNEL
   234 EXPORT_C
   235 #endif
   236 DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c(const TBusType aBusType, const TChannelDuplex aChanDuplex)
   237 	: DIicBusChannelMaster(aBusType,aChanDuplex)
   238 	{
   239 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   240 #ifndef STANDALONE_CHANNEL
   241 	iChannelNumber = AssignChanNum();
   242 #endif
   243 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c, iChannelNumber=%d\n",iChannelNumber));
   244 	}
   245 
   246 TInt DSimulatedIicBusChannelMasterI2c::DoCreate()
   247 	{
   248 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoCreate\n"));
   249 	TInt r=Init();	// PIL Base class initialisation
   250 	r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KI2cThreadPriority,KI2cThreadName);
   251 	if(r == KErrNone)
   252 		SetDfcQ((TDfcQue*)iDynamicDfcQ);
   253 	DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(this,EFalse);
   254 	return r;
   255 	}
   256 
   257 TInt DSimulatedIicBusChannelMasterI2c::CheckHdr(TDes8* aHdr)
   258 	{
   259 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr\n"));
   260 
   261 	TConfigI2cBufV01* i2cBuf = (TConfigI2cBufV01*)aHdr;
   262 	TConfigI2cV01* i2cPtr = &((*i2cBuf)());
   263 
   264 	// Check that the values for address type, clock speed, user operation and endianness are recognised
   265 	if((i2cPtr->iAddrType < 0) || (i2cPtr->iAddrType > EI2cAddr10Bit))
   266 		{
   267 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised address type identifier %d\n",i2cPtr->iAddrType));
   268 		return KErrArgument;
   269 		}
   270 	if(i2cPtr->iClkSpeedHz < 0)
   271 		{
   272 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative clock speed specified %d\n",i2cPtr->iClkSpeedHz));
   273 		return KErrArgument;
   274 		}
   275 	if((i2cPtr->iEndianness < 0) || (i2cPtr->iEndianness > ELittleEndian))
   276 		{
   277 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr unrecognised endianness identifier %d\n",i2cPtr->iEndianness));
   278 		return KErrArgument;
   279 		}
   280 	// Values for the timeout period are arbitrary - can only check it is not a negative value
   281 	if(i2cPtr->iTimeoutPeriod < 0)
   282 		{
   283 		I2C_PRINT(("ERROR: DSimulatedIicBusChannelMasterI2c::CheckHdr negative timeout period %d\n",i2cPtr->iTimeoutPeriod));
   284 		return KErrArgument;
   285 		}
   286 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr address type = %d\n",i2cPtr->iAddrType));
   287 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr clock speed ID = %d\n",i2cPtr->iClkSpeedHz));
   288 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iEndianness ID = %d\n",i2cPtr->iEndianness));
   289 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::CheckHdr iTimeoutPeriod = %d\n",i2cPtr->iTimeoutPeriod));
   290 	return KErrNone;
   291 	}
   292 
   293 	// Gateway function for PSL implementation, invoked for DFC processing
   294 TInt DSimulatedIicBusChannelMasterI2c::DoRequest(TIicBusTransaction* aTransaction)
   295 	{
   296 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest invoked with aTransaction=0x%x\n",aTransaction));
   297 	TInt r = KErrNone;
   298 
   299 #ifdef IIC_INSTRUMENTATION_MACRO
   300 	IIC_MPROCESSTRANS_START_PSL_TRACE;
   301 #endif
   302 
   303 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHeader=0x%x\n",GetTransactionHeader(aTransaction)));
   304 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(aTransaction)));
   305 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(aTransaction)));
   306 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iCallback=0x%x\n",GetTransCallback(aTransaction)));
   307 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans aTransaction->iFlags=0x%x\n",GetTransFlags(aTransaction)));
   308 
   309 	I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::DoRequest, iHeader info \n"));
   310 	TDes8* bufPtr = GetTransactionHeader(aTransaction);
   311 	if(bufPtr == NULL)
   312 		{
   313 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest ERROR - NULL header\n"));
   314 		return KErrCorrupt;
   315 		}
   316 	TConfigI2cV01 *buf = (TConfigI2cV01 *)(bufPtr->Ptr());
   317 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header address type=0x%x\n",buf->iAddrType));
   318 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header clock speed=0x%x\n",buf->iClkSpeedHz));
   319 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header endianness=0x%x\n",buf->iEndianness));
   320 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::DoRequest, header timeout period=0x%x\n",buf->iTimeoutPeriod));
   321 	(void)buf;	// Silence compiler when I2C_PRINT not used
   322 
   323 	TInt aTime=1000000/NKern::TickPeriod();
   324 	r = StartSlaveTimeOutTimer(aTime);
   325 	I2C_PRINT(("\nDSimulatedIicBusChannelMasterI2c::ProcessTrans, iHalfDuplexTrans info \n"));
   326 	TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(aTransaction);
   327 	while(halfDuplexPtr != NULL)
   328 		{
   329 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer type=0x%x\n",GetTferType(halfDuplexPtr)));
   330 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr)));
   331 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr)));
   332 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr)));
   333 		halfDuplexPtr=GetTferNextTfer(halfDuplexPtr);
   334 		}
   335 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - End of iHalfDuplexTrans info"));
   336 
   337 	while(IsRequestDelayed(this))
   338 		{
   339 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - starting Sleep...\n"));
   340 		NKern::Sleep(1000);	// 1000 is arbitrary
   341 		I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - completed Sleep, check if still delayed\n"));
   342 		}; 
   343 
   344 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::ProcessTrans - exiting\n"));
   345 
   346 	return r;
   347 	}
   348 
   349 
   350 TBool DSimulatedIicBusChannelMasterI2c::IsRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan)
   351 	{
   352 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::IsRequestDelayed invoked for aChan=0x%x\n",aChan));
   353 	return aChan->iReqDelayed;
   354 	}
   355 
   356 void DSimulatedIicBusChannelMasterI2c::SetRequestDelayed(DSimulatedIicBusChannelMasterI2c* aChan,TBool aDelay) 
   357 	{
   358 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay));
   359 	aChan->iReqDelayed=aDelay;
   360 	}
   361 
   362 TInt DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout()
   363 	{
   364 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::HandleSlaveTimeout invoked for this=0x%x\n",this));
   365 	return KErrTimedOut;
   366 	}
   367 
   368 TInt DSimulatedIicBusChannelMasterI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   369 	{
   370 	I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::StaticExtension\n"));
   371 	TInt r = KErrNone;
   372 #ifdef IIC_INSTRUMENTATION_MACRO
   373 	IIC_MSTATEXT_START_PSL_TRACE;
   374 #endif
   375 	(void)aParam1;
   376 	(void)aParam2;
   377 	
   378 	// Test values of aFunction were shifted left one place by the (test) client driver
   379 	// Return to its original value.
   380 	if(aFunction>KTestControlIoPilOffset)
   381 		aFunction >>= 1;
   382 	switch(aFunction)
   383 		{
   384 		case(RBusDevIicClient::ECtlIoDumpChan):
   385 			{
   386 #ifdef _DEBUG
   387 			DumpChannel();
   388 #endif
   389 			break;
   390 			}
   391 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
   392 			{
   393 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Blocking request completion\n"));
   394 			SetRequestDelayed(this, ETrue);
   395 			break;
   396 			}
   397 		case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
   398 			{
   399 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c::Unlocking request completion\n"));
   400 			SetRequestDelayed(this, EFalse);
   401 			break;
   402 			}
   403 		case(RBusDevIicClient::ECtlIoDeRegChan):
   404 			{
   405 #ifndef STANDALONE_CHANNEL
   406 #ifdef IIC_INSTRUMENTATION_MACRO
   407 	IIC_DEREGISTERCHAN_START_PSL_TRACE;
   408 #endif
   409 			I2C_PRINT(("DSimulatedIicBusChannelMasterI2c: deregister channel\n"));
   410 			r=DIicBusController::DeRegisterChannel(this);
   411 
   412 #ifdef IIC_INSTRUMENTATION_MACRO
   413 	IIC_DEREGISTERCHAN_END_PSL_TRACE;
   414 #endif/*IIC_INSTRUMENTATION_MACRO*/
   415 	
   416 #else/*STANDALONE_CHANNEL*/
   417 			r = KErrNotSupported;
   418 #endif/*STANDALONE_CHANNEL*/
   419 			break;
   420 			}
   421 		default:
   422 			{
   423 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
   424 			r=KErrNotSupported;
   425 			}
   426 		}
   427 		
   428 #ifdef IIC_INSTRUMENTATION_MACRO
   429 	IIC_MSTATEXT_END_PSL_TRACE;
   430 #endif		
   431 	return r;
   432 	}
   433 
   434 //#ifdef MASTER_MODE
   435 #endif
   436 
   437 #ifdef SLAVE_MODE
   438 
   439 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
   440 	{
   441 	// To support simulating an asynchronous capture operation
   442 	// NOTE: this will be invoked in the context of DfcThread1
   443 	I2C_PRINT(("SlaveAsyncSimCallback\n"));
   444 	DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
   445 	TInt r=KErrNone;// Just simulate successful capture
   446 #ifdef IIC_INSTRUMENTATION_MACRO
   447 	IIC_SCAPTCHANASYNC_END_PSL_TRACE;
   448 #endif
   449 	channel->ChanCaptureCb(r);
   450 	}
   451 
   452 #ifdef STANDALONE_CHANNEL
   453 EXPORT_C
   454 #endif
   455 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
   456 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
   457 	iBlockedTrigger(0),iBlockNotification(EFalse),
   458 	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this)
   459 	{
   460 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
   461 #ifndef STANDALONE_CHANNEL
   462 	iChannelNumber = AssignChanNum();
   463 #endif
   464 	iChannelId = AssignSlaveChanId();
   465 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, iChannelNumber=%d, iChannelId=0x%x\n",iChannelNumber,iChannelId));
   466 	}
   467 
   468 DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c()
   469 	{
   470 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::~DSimulatedIicBusChannelSlaveI2c\n"));
   471 	}
   472 
   473 TInt DSimulatedIicBusChannelSlaveI2c::DoCreate()
   474 	{
   475 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoCreate\n"));
   476 	TInt r=Init();	// PIL Base class initialisation
   477 	return r;
   478 	}
   479 
   480 
   481 TInt DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl(TBool aAsynch)
   482 	{
   483 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl\n"));
   484 	TInt r = KErrNone;
   485 	if(aAsynch)
   486 		{
   487 #ifdef IIC_INSTRUMENTATION_MACRO
   488 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
   489 #endif
   490 		// To simulate an asynchronous capture operation, just set a timer to expire
   491 		iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
   492 		}
   493 	else
   494 		{
   495 #ifdef IIC_INSTRUMENTATION_MACRO
   496 	IIC_SCAPTCHANSYNC_START_PSL_TRACE;
   497 #endif
   498 		// PSL processing would happen here ...
   499 		// Expected to include implementation of the header configuration information 
   500 
   501 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChannelPsl (synchronous) ... no real processing to do \n"));
   502 
   503 #ifdef IIC_INSTRUMENTATION_MACRO
   504 	IIC_SCAPTCHANSYNC_END_PSL_TRACE;
   505 #endif
   506 		}
   507 
   508 	return r;
   509 	}
   510 
   511 TInt DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl()
   512 	{
   513 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl\n"));
   514 #ifdef IIC_INSTRUMENTATION_MACRO
   515 	IIC_SRELCHAN_START_PSL_TRACE;
   516 #endif
   517 	TInt r = KErrNone;
   518 
   519 	// PSL-specific processing would happen here ...
   520 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ReleaseChannelPsl ... no real processing to do \n"));
   521 
   522 #ifdef IIC_INSTRUMENTATION_MACRO
   523 	IIC_SRELCHAN_END_PSL_TRACE;
   524 #endif
   525 
   526 	return r;
   527 	}
   528 
   529 
   530 TInt DSimulatedIicBusChannelSlaveI2c::PrepareTrigger(TInt aTrigger)
   531 	{
   532 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger\n"));
   533 #ifdef IIC_INSTRUMENTATION_MACRO
   534 //	IIC_SNOTIFTRIG_START_PSL;
   535 #endif
   536 	TInt r=KErrNotSupported;
   537 	if(aTrigger&EReceive)
   538 		{
   539 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Rx\n"));
   540 		r=KErrNone;
   541 		}
   542 	if(aTrigger&ETransmit)
   543 		{
   544 		I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::PrepareTrigger - prepare hardware for Tx\n"));
   545 		r=KErrNone;
   546 		}
   547 	// Check for any additional triggers and make the necessary preparation
   548 	// ... do nothing in simulated PSL
   549 	r=KErrNone;
   550 
   551 #ifdef IIC_INSTRUMENTATION_MACRO
   552 //	IIC_SNOTIFTRIG_END_PSL;
   553 #endif
   554 	return r;
   555 	}
   556 
   557 TInt DSimulatedIicBusChannelSlaveI2c::CheckHdr(TDes8* /*aHdr*/)
   558 	{
   559 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::CheckHdr\n"));
   560 	return KErrNone;
   561 	}
   562 
   563 TInt DSimulatedIicBusChannelSlaveI2c::DoRequest(TInt aOperation)
   564 	{
   565 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DoRequest\n"));
   566 	TInt r = KErrNone;
   567 
   568 	switch(aOperation)
   569 		{
   570 		case(ESyncConfigPwrUp):
   571 			{
   572 			r=CaptureChannelPsl(EFalse);
   573 			break;
   574 			};
   575 		case(EAsyncConfigPwrUp):
   576 			{
   577 			r=CaptureChannelPsl(ETrue);
   578 			break;
   579 			};
   580 		case(EPowerDown):
   581 			{
   582 			r=ReleaseChannelPsl();
   583 			break;
   584 			};
   585 		case(EAbort):
   586 			{
   587 			break;
   588 			};
   589 		default:
   590 			{
   591 			// The remaining operations are to instigate an Rx, Tx or just prepare for
   592 			// overrun/underrun/bus error notifications.
   593 			// Handle all these, and any unsupported operation in the following function
   594 			r=PrepareTrigger(aOperation);
   595 			break;
   596 			};
   597 		}
   598 	return r;
   599 	}
   600 
   601 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback*  aCb)
   602 	{
   603 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData\n"));
   604 	// fills in iReturn, iRxWords and/or iTxWords
   605 	//
   606 	if(aTrigger & ERxAllBytes)
   607 		{
   608 		aCb->SetRxWords(iNumWordsWereRx);
   609 		if(iRxTxUnderOverRun & ERxUnderrun)
   610 			{
   611 			aTrigger|=ERxUnderrun;
   612 			iRxTxUnderOverRun&= ~ERxUnderrun;
   613 			}
   614 		if(iRxTxUnderOverRun & ERxOverrun)
   615 			{
   616 			aTrigger|=ERxOverrun;
   617 			iRxTxUnderOverRun&= ~ERxOverrun;
   618 			}
   619 		}
   620 	if(aTrigger & ETxAllBytes)
   621 		{
   622 		aCb->SetTxWords(iNumWordsWereTx);
   623 		if(iRxTxUnderOverRun & ETxUnderrun)
   624 			{
   625 			aTrigger|=ETxUnderrun;
   626 			iRxTxUnderOverRun&= ~ETxUnderrun;
   627 			}
   628 		if(iRxTxUnderOverRun & ETxOverrun)
   629 			{
   630 			aTrigger|=ETxOverrun;
   631 			iRxTxUnderOverRun&= ~ETxOverrun;
   632 			}
   633 		}
   634 
   635 	aCb->SetTrigger(aTrigger);
   636 	}
   637 
   638 TInt DSimulatedIicBusChannelSlaveI2c::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2)
   639 	{
   640 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::StaticExtension\n"));
   641 #ifdef IIC_INSTRUMENTATION_MACRO
   642 	IIC_SSTATEXT_START_PSL_TRACE;
   643 #endif
   644 	// Test values of aFunction were shifted left one place by the (test) client driver
   645 	// and for Slave values the two msb were cleared
   646 	// Return to its original value.
   647 	if(aFunction>KTestControlIoPilOffset)
   648 		{
   649 		aFunction |= 0xC0000000;
   650 		aFunction >>= 1;
   651 		}
   652 	TInt r = KErrNone;
   653 	switch(aFunction)
   654 		{
   655 		case(RBusDevIicClient::ECtlIoDumpChan):
   656 			{
   657 #ifdef _DEBUG
   658 			DumpChannel();
   659 #endif
   660 			break;
   661 			}
   662 		case(RBusDevIicClient::ECtlIoDeRegChan):
   663 			{
   664 #ifndef STANDALONE_CHANNEL
   665 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: deregister channel\n"));
   666 			// DIicBusController::DeRegisterChannel just removes the channel from the array of channels available 
   667 			r=DIicBusController::DeRegisterChannel(this);
   668 #else
   669 			r = KErrNotSupported;
   670 #endif
   671 			break;
   672 			}
   673 
   674 		case(RBusDevIicClient::ECtrlIoRxWords):
   675 			{
   676 			// Simulate receipt of a number of bytes
   677 			// aParam1 represents the ChannelId
   678 			// aParam2 specifies the number of bytes
   679 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, channelId=0x%x, numBytes=0x%x\n",aParam1,aParam2));
   680 
   681 			// Load the buffer with simulated data
   682 			if(iRxBuf == NULL)
   683 				{
   684 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxWords, ERROR, iRxBuf == NULL\n"));
   685 				r=KErrGeneral;
   686 				break;
   687 				}
   688 			// Check for overrun-underrun conditions
   689 			TInt trigger=ERxAllBytes;
   690 			iNumWordsWereRx=(TInt8)((TInt)aParam2);
   691 			iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
   692 			if(iDeltaWordsToRx>0)
   693 				{
   694 				iNumWordsWereRx=iNumRxWords;
   695 				iRxTxUnderOverRun |= ERxOverrun;
   696 				}
   697 			if(iDeltaWordsToRx<0)
   698 				iRxTxUnderOverRun |= ERxUnderrun;
   699 
   700 			TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
   701 			TInt8 startVal=0x10;
   702 			for(TInt8 numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
   703 				{
   704 				for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
   705 					{
   706 					*ptr=startVal;
   707 					}
   708 				}
   709 			if(iBlockNotification == EFalse)
   710 				{
   711 				//
   712 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   713 				NotifyClient(trigger);
   714 				}
   715 			else
   716 				{
   717 				// Save the trigger value to notify when prompted.
   718 				iBlockedTrigger=trigger;
   719 				}
   720 			break;
   721 
   722 			}
   723 
   724 		case(RBusDevIicClient::ECtrlIoUnblockNotification):
   725 			{
   726 			iBlockNotification=EFalse;
   727 			NotifyClient(iBlockedTrigger);
   728 			iBlockedTrigger=0;
   729 			break;
   730 			}
   731 
   732 		case(RBusDevIicClient::ECtrlIoBlockNotification):
   733 			{
   734 			iBlockNotification=ETrue;
   735 			break;
   736 			}
   737 
   738 		case(RBusDevIicClient::ECtrlIoTxWords):
   739 			{
   740 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
   741 			// Simulate transmission of a number of bytes
   742 			// aParam1 represents the ChannelId
   743 			// aParam2 specifies the number of bytes
   744 			// Load the buffer with simulated data
   745 			if(iTxBuf == NULL)
   746 				{
   747 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxWords, ERROR, iTxBuf==NULL\n"));
   748 				r=KErrGeneral;
   749 				break;
   750 				}
   751 			// Check for overrun-underrun conditions
   752 			TInt trigger=ETxAllBytes;
   753 			iNumWordsWereTx=(TInt8)((TInt)aParam2);
   754 			iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
   755 			if(iDeltaWordsToTx>0)
   756 				{
   757 				iNumWordsWereTx=iNumTxWords;
   758 				iRxTxUnderOverRun |= ETxUnderrun;
   759 				}
   760 			if(iDeltaWordsToTx<0)
   761 				iRxTxUnderOverRun |= ETxOverrun;
   762 
   763 			// Initialise the check buffer
   764 			if(iTxCheckBuf!=NULL)
   765 				delete iTxCheckBuf;
   766 			// iTxCheckBuf is a member of class DSimulatedIicBusChannelSlaveI2c, which 
   767 			// is created here, and deleted not in ~DSimulatedIicBusChannelSlaveI2c()
   768 			// but from client side. This is because in t_iic, 
   769 			// we put a memory leak checking macro __KHEAP_MARKEND before
   770 			// the pdd gets unloaded which will call ~DSimulatedIicBusChannelSlaveI2c().  
   771 			// If we delete iTxCheckBuf in ~DSimulatedIicBusChannelSlaveI2c(),
   772 			// we will get a memory leak panic in __KHEAP_MARKEND.
   773 			// To support the test code, we moved iTxCheckBuf deletion to the client side. 
   774 			iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
   775 			memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
   776 
   777 			TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
   778 			TInt8* dstPtr=iTxCheckBuf;
   779 			for(TInt8 numWords=0; numWords<iNumWordsWereTx; numWords++)
   780 				{
   781 				for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
   782 					*dstPtr++=*srcPtr++;
   783 				}
   784 			if(iBlockNotification == EFalse)
   785 				{
   786 				//
   787 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   788 				NotifyClient(trigger);
   789 				}
   790 			else
   791 				{
   792 				// Save the trigger value to notify when prompted.
   793 				iBlockedTrigger=trigger;
   794 				}
   795 			break;
   796 			}
   797 
   798 		case(RBusDevIicClient::ECtrlIoRxTxWords):
   799 			{
   800 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
   801 			// Simulate transmission of a number of bytes
   802 			// aParam1 represents the ChannelId
   803 			// aParam2 represents a pointer to the two numbers of bytes
   804 			// Check the buffers are available
   805 			if(iTxBuf == NULL)
   806 				{
   807 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iTxBuf==NULL\n"));
   808 				r=KErrGeneral;
   809 				break;
   810 				}
   811 			if(iRxBuf == NULL)
   812 				{
   813 				I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoRxTxWords, ERROR, iRxBuf==NULL\n"));
   814 				r=KErrGeneral;
   815 				break;
   816 				}
   817 			// Check for overrun-underrun conditions
   818 			TInt trigger=ETxAllBytes|ERxAllBytes;
   819 			iNumWordsWereRx=(TInt8)(*(TInt*)aParam2);
   820 			TInt* tempPtr=((TInt*)(aParam2));
   821 			iNumWordsWereTx=(TInt8)(*(++tempPtr));
   822 
   823 			iDeltaWordsToTx = (TInt8)(iNumWordsWereTx - iNumTxWords);
   824 			if(iDeltaWordsToTx>0)
   825 				{
   826 				iNumWordsWereTx=iNumTxWords;
   827 				iRxTxUnderOverRun |= ETxUnderrun;
   828 				}
   829 			if(iDeltaWordsToTx<0)
   830 				iRxTxUnderOverRun |= ETxOverrun;
   831 
   832 
   833 			iDeltaWordsToRx = (TInt8)(iNumWordsWereRx - iNumRxWords);
   834 			if(iDeltaWordsToRx>0)
   835 				{
   836 				iNumWordsWereRx=iNumRxWords;
   837 				iRxTxUnderOverRun |= ERxOverrun;
   838 				}
   839 			if(iDeltaWordsToRx<0)
   840 				iRxTxUnderOverRun |= ERxUnderrun;
   841 
   842 
   843 			// Initialise the buffers
   844 			if(iTxCheckBuf!=NULL)
   845 				delete iTxCheckBuf;
   846 			iTxCheckBuf = new TInt8[iNumTxWords*iTxGranularity];
   847 			memset(iTxCheckBuf,0,(iNumTxWords*iTxGranularity));
   848 
   849 			TInt8* srcPtr=(TInt8*)(iTxBuf+iTxOffset);
   850 			TInt8* dstPtr=iTxCheckBuf;
   851 			TInt8 numWords=0;
   852 			for(numWords=0; numWords<iNumWordsWereTx; numWords++)
   853 				{
   854 				for(TInt wordByte=0; wordByte<iTxGranularity; wordByte++)
   855 					*dstPtr++=*srcPtr++;
   856 				}
   857 
   858 			TInt8* ptr=(TInt8*)(iRxBuf+iRxOffset);
   859 			TInt8 startVal=0x10;
   860 			for(numWords=0; numWords<iNumWordsWereRx; numWords++,startVal++)
   861 				{
   862 				for(TInt wordByte=0; wordByte<iRxGranularity; wordByte++,ptr++)
   863 					{
   864 					*ptr=startVal;
   865 					}
   866 				}		
   867 			
   868 			if(iBlockNotification == EFalse)
   869 				{
   870 				//
   871 				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
   872 				NotifyClient(trigger);
   873 				}
   874 			else
   875 				{
   876 				// Save the trigger value to notify when prompted.
   877 				iBlockedTrigger=trigger;
   878 				}
   879 			break;
   880 			}
   881 
   882 		case(RBusDevIicClient::ECtrlIoTxChkBuf):
   883 			{
   884 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtrlIoTxChkBuf, aParam1=0x%x, aParam2=0x%x\n",aParam1,aParam2));
   885 			// Return the address of iTxCheckBuf to the address pointed to by a1
   886 			// Both the simulated bus channel and the slave client are resident in the client process
   887 			// so the client can use the pointer value for direct access
   888 			TInt8** ptr = (TInt8**)aParam1;
   889 			*ptr=iTxCheckBuf;
   890 			break;
   891 			}
   892 
   893 		case(RBusDevIicClient::ECtlIoBusError):
   894 			{
   895 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c: ECtlIoBusError\n"));
   896 			NotifyClient(EGeneralBusError);
   897 			break;
   898 			}
   899 
   900 		case(RBusDevIicClient::ECtrlIoUpdTimeout):
   901 			{
   902 			// For this test, do the following for the Master and Client timeout values:
   903 			// (1) Read the current timeout value and check that it is set to the default
   904 			// (2) Check setting to a neagtive value fails
   905 			// (3) Set it to a new, different value
   906 			// (4) Read it back to check success
   907 			// (5) Return to the original value, and readback to confirm
   908 			I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c ECtrlIoUpdTimeout \n"));
   909 
   910 			TInt timeout = 0;
   911 			TInt r=KErrNone;
   912 			// Master timeout
   913 			timeout=GetMasterWaitTime();
   914 			if(timeout!=KSlaveDefMWaitTime)
   915 				{
   916 				I2C_PRINT(("ERROR: Initial Master Wait time != KSlaveDefMWaitTime (=%d) \n",timeout));
   917 				return KErrGeneral;
   918 				}
   919 			r=SetMasterWaitTime(-1);
   920 			if(r!=KErrArgument)
   921 				{
   922 				I2C_PRINT(("ERROR: Attempt to set negative Master wait time not rejected\n"));
   923 				return KErrGeneral;
   924 				}
   925 			r=SetMasterWaitTime(KSlaveDefCWaitTime);
   926 			if(r!=KErrNone)
   927 				{
   928 				I2C_PRINT(("ERROR: Attempt to set new valid Master wait time (%d) rejected\n",KSlaveDefCWaitTime));
   929 				return KErrGeneral;
   930 				}
   931 			timeout=GetMasterWaitTime();
   932 			if(timeout!=KSlaveDefCWaitTime)
   933 				{
   934 				I2C_PRINT(("ERROR: Master Wait time read back has unexpected value (=%d) \n",timeout));
   935 				return KErrGeneral;
   936 				}
   937 			r=SetMasterWaitTime(KSlaveDefMWaitTime);
   938 			if(r!=KErrNone)
   939 				{
   940 				I2C_PRINT(("ERROR: Attempt to set reset Master wait time (%d) rejected\n",KSlaveDefMWaitTime));
   941 				return KErrGeneral;
   942 				}
   943 			timeout=GetMasterWaitTime();
   944 			if(timeout!=KSlaveDefMWaitTime)
   945 				{
   946 				I2C_PRINT(("ERROR: Master Wait time read back of reset time has unexpected value (=%d) \n",timeout));
   947 				return KErrGeneral;
   948 				}
   949 			// Client timeout
   950 			timeout=GetClientWaitTime();
   951 			if(timeout!=KSlaveDefCWaitTime)
   952 				{
   953 				I2C_PRINT(("ERROR: Initial Client Wait time != KSlaveDefCWaitTime (=%d) \n",timeout));
   954 				return KErrGeneral;
   955 				}
   956 			r=SetClientWaitTime(-1);
   957 			if(r!=KErrArgument)
   958 				{
   959 				I2C_PRINT(("ERROR: Attempt to set negative Client wait time not rejected\n"));
   960 				return KErrGeneral;
   961 				}
   962 			r=SetClientWaitTime(KSlaveDefMWaitTime+1);
   963 			if(r!=KErrNone)
   964 				{
   965 				I2C_PRINT(("ERROR: Attempt to set new valid Client wait time (%d) rejected\n",KSlaveDefMWaitTime));
   966 				return KErrGeneral;
   967 				}
   968 			timeout=GetClientWaitTime();
   969 			if(timeout!=KSlaveDefMWaitTime+1)
   970 				{
   971 				I2C_PRINT(("ERROR: Client Wait time read back has unexpected value (=%d) \n",timeout));
   972 				return KErrGeneral;
   973 				}
   974 			r=SetClientWaitTime(KSlaveDefCWaitTime);
   975 			if(r!=KErrNone)
   976 				{
   977 				I2C_PRINT(("ERROR: Attempt to set reset Client wait time (%d) rejected\n",KSlaveDefCWaitTime));
   978 				return KErrGeneral;
   979 				}
   980 			timeout=GetClientWaitTime();
   981 			if(timeout!=KSlaveDefCWaitTime)
   982 				{
   983 				I2C_PRINT(("ERROR: Client Wait time read back of reset time has unexpected value (=%d) \n",timeout));
   984 				return KErrGeneral;
   985 				}
   986 			break;
   987 			}
   988 
   989 		default:
   990 			{
   991 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
   992 			r=KErrNotSupported;
   993 			}
   994 		}
   995 #ifdef IIC_INSTRUMENTATION_MACRO
   996 	IIC_SSTATEXT_END_PSL_TRACE;
   997 #endif
   998 	return r;
   999 	}
  1000 
  1001 
  1002 
  1003 //#ifdef MASTER_MODE
  1004 #endif
  1005 
  1006 #if defined(MASTER_MODE) && defined(SLAVE_MODE)
  1007 #ifdef STANDALONE_CHANNEL
  1008 EXPORT_C
  1009 #endif
  1010 DSimulatedIicBusChannelMasterSlaveI2c::DSimulatedIicBusChannelMasterSlaveI2c(TBusType /*aBusType*/, TChannelDuplex aChanDuplex, DSimulatedIicBusChannelMasterI2c* aMasterChan, DSimulatedIicBusChannelSlaveI2c* aSlaveChan)
  1011 	: DIicBusChannelMasterSlave(EI2c, aChanDuplex, aMasterChan, aSlaveChan)
  1012 	{}
  1013 
  1014 TInt DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension(TUint aFunction, TAny* /*aParam1*/, TAny* /*aParam2*/)
  1015 	{
  1016 	I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::StaticExtension, aFunction=0x%x\n",aFunction));
  1017 	TInt r = KErrNone;
  1018 
  1019 	// Test values of aFunction were shifted left one place by the (test) client driver
  1020 	// Return to its original value.
  1021 	if(aFunction>KTestControlIoPilOffset)
  1022 		aFunction >>= 1;
  1023 	switch(aFunction)
  1024 		{
  1025 		case(RBusDevIicClient::ECtlIoDumpChan):
  1026 			{
  1027 #ifdef _DEBUG
  1028 			DumpChannel();
  1029 #endif
  1030 			break;
  1031 			}
  1032 		case(RBusDevIicClient::ECtlIoDeRegChan):
  1033 			{
  1034 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c: deregister channel\n"));
  1035 #ifndef STANDALONE_CHANNEL
  1036 			r=DIicBusController::DeRegisterChannel(this);
  1037 #else
  1038 			return KErrNotSupported;
  1039 #endif
  1040 			break;
  1041 			}
  1042 		case(RBusDevIicClient::ECtlIoBlockReqCompletion):
  1043 			{
  1044 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Blocking request completion\n"));
  1045 			((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), ETrue);
  1046 			break;
  1047 			}
  1048 		case(RBusDevIicClient::ECtlIoUnblockReqCompletion):
  1049 			{
  1050 			I2C_PRINT(("DSimulatedIicBusChannelMasterSlaveI2c::Unlocking request completion\n"));
  1051 			((DSimulatedIicBusChannelMasterI2c*)iMasterChannel)->SetRequestDelayed(((DSimulatedIicBusChannelMasterI2c*)iMasterChannel), EFalse);
  1052 			break;
  1053 			}
  1054 		default:
  1055 			{
  1056 			Kern::Printf("aFunction %d is not recognised \n",aFunction);
  1057 			r=KErrNotSupported;
  1058 			}
  1059 		}
  1060 	return r;
  1061 	}
  1062 
  1063 
  1064 //#if defined(MASTER_MODE) && defined(SLAVE_MODE)
  1065 #endif
  1066 
  1067 
  1068