kernel/eka/drivers/iic/iic.cpp
changeset 0 a41df078684a
child 199 189ece41fa29
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 // e32\drivers\iic.cpp
       
    15 // IIC Controller and public API Implementation
       
    16 //
       
    17 
       
    18 #include <drivers/iic.h>
       
    19 #include <drivers/iic_channel.h>
       
    20 #include "iic_priv.h"
       
    21 
       
    22 #ifdef IIC_INSTRUMENTATION_MACRO
       
    23 #include <drivers/iic_trace.h>
       
    24 #endif
       
    25 
       
    26 // Global Controller pointer
       
    27 static DIicBusController* TheController = NULL;
       
    28 
       
    29 //
       
    30 //		Implementation of generic IicBus API for client interface
       
    31 //
       
    32 EXPORT_C TInt IicBus::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction)
       
    33 	{
       
    34 #ifdef IIC_INSTRUMENTATION_MACRO
       
    35 	IIC_MQTRANSSYNC_START_PIL_TRACE;
       
    36 #endif
       
    37 	TInt r=TheController->QueueTransaction(aBusId, aTransaction);
       
    38 
       
    39 #ifdef IIC_INSTRUMENTATION_MACRO
       
    40 	IIC_MQTRANSSYNC_END_PIL_TRACE;
       
    41 #endif
       
    42 	return r;
       
    43 	}
       
    44 
       
    45 EXPORT_C TInt IicBus::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback* aCallback)
       
    46 	{
       
    47 #ifdef IIC_INSTRUMENTATION_MACRO
       
    48 	IIC_MQTRANSASYNC_START_PIL_TRACE;
       
    49 #endif
       
    50 	TInt r=TheController->QueueTransaction(aBusId, aTransaction, aCallback);
       
    51 
       
    52 #ifdef IIC_INSTRUMENTATION_MACRO
       
    53 	IIC_MQTRANSASYNC_END_PIL_TRACE;
       
    54 #endif
       
    55 	return r;
       
    56 	}
       
    57 
       
    58 EXPORT_C TInt IicBus::CancelTransaction(TInt aBusId, TIicBusTransaction* aTransaction)
       
    59 	{
       
    60 #ifdef IIC_INSTRUMENTATION_MACRO
       
    61 	IIC_MCANCELTRANS_START_PIL_TRACE;
       
    62 #endif
       
    63 	TInt r=TheController->CancelTransaction(aBusId, aTransaction);
       
    64 
       
    65 #ifdef IIC_INSTRUMENTATION_MACRO
       
    66 	IIC_MCANCELTRANS_END_PIL_TRACE;
       
    67 #endif
       
    68 	return r;
       
    69 	}
       
    70 
       
    71 EXPORT_C TInt IicBus::CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch)
       
    72 	{
       
    73 #ifdef IIC_INSTRUMENTATION_MACRO
       
    74 	if(!aAsynch)
       
    75 		{
       
    76 		IIC_SCAPTCHANSYNC_START_PIL_TRACE;
       
    77 		}
       
    78 	else
       
    79 		{
       
    80 		IIC_SCAPTCHANASYNC_START_PIL_TRACE;
       
    81 		}
       
    82 #endif
       
    83 	TInt r=TheController->CaptureChannel(aBusId, aConfigHdr, aCallback, aChannelId, aAsynch);
       
    84 
       
    85 #ifdef IIC_INSTRUMENTATION_MACRO
       
    86 	if(!aAsynch)
       
    87 		{
       
    88 		IIC_SCAPTCHANSYNC_END_PIL_TRACE;
       
    89 		}
       
    90 #endif
       
    91 	return r;
       
    92 	}
       
    93 
       
    94 EXPORT_C TInt IicBus::ReleaseChannel(TInt aChannelId)
       
    95 	{
       
    96 #ifdef IIC_INSTRUMENTATION_MACRO
       
    97 	IIC_SRELCHAN_START_PIL_TRACE;
       
    98 #endif
       
    99 	TInt r=TheController->ReleaseChannel(aChannelId);
       
   100 
       
   101 #ifdef IIC_INSTRUMENTATION_MACRO
       
   102 	IIC_SRELCHAN_END_PIL_TRACE;
       
   103 #endif
       
   104 	return r;
       
   105 	}
       
   106 
       
   107 EXPORT_C TInt IicBus::RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   108 	{
       
   109 #ifdef IIC_INSTRUMENTATION_MACRO
       
   110 	IIC_SREGRXBUF_START_PIL_TRACE;
       
   111 #endif
       
   112 	TInt r=TheController->RegisterRxBuffer(aChannelId, aRxBuffer, aBufGranularity, aNumWords, aOffset);
       
   113 
       
   114 #ifdef IIC_INSTRUMENTATION_MACRO
       
   115 	IIC_SREGRXBUF_END_PIL_TRACE;
       
   116 #endif
       
   117 	return r;
       
   118 	}
       
   119 
       
   120 EXPORT_C TInt IicBus::RegisterTxBuffer(TInt aChannelId, TPtr8 aTxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   121 	{
       
   122 #ifdef IIC_INSTRUMENTATION_MACRO
       
   123 	IIC_SREGTXBUF_START_PIL_TRACE;
       
   124 #endif
       
   125 	TInt r=TheController->RegisterTxBuffer(aChannelId, aTxBuffer, aBufGranularity, aNumWords, aOffset);
       
   126 
       
   127 #ifdef IIC_INSTRUMENTATION_MACRO
       
   128 	IIC_SREGTXBUF_END_PIL_TRACE;
       
   129 #endif
       
   130 	return r;
       
   131 	}
       
   132 
       
   133 EXPORT_C TInt IicBus::SetNotificationTrigger(TInt aChannelId, TInt aTrigger)
       
   134 	{
       
   135 #ifdef IIC_INSTRUMENTATION_MACRO
       
   136 	IIC_SNOTIFTRIG_START_PIL_TRACE;
       
   137 #endif
       
   138 	TInt r=TheController->SetNotificationTrigger(aChannelId, aTrigger);
       
   139 
       
   140 #ifdef IIC_INSTRUMENTATION_MACRO
       
   141 	IIC_SNOTIFTRIG_END_PIL_TRACE;
       
   142 #endif
       
   143 	return r;
       
   144 	}
       
   145 
       
   146 EXPORT_C TInt IicBus::StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, TAny* aParam2)
       
   147 	{
       
   148 	return(TheController->StaticExtension(aId, aFunction, aParam1, aParam2));
       
   149 	}
       
   150 
       
   151 
       
   152 //
       
   153 //		Bus Controller
       
   154 //
       
   155 
       
   156 //  auxiliary function for ordering entries in the array of channels
       
   157 TInt DIicBusController::OrderEntries(const DIicBusChannel& aMatch, const DIicBusChannel& aEntry)
       
   158 	{
       
   159 	TUint8 l=(TUint8)aMatch.ChannelNumber();
       
   160 	TUint8 r=(TUint8)aEntry.ChannelNumber();
       
   161 	if(l>r)
       
   162 		return -1;
       
   163 	else if(l<r)
       
   164 		return 1;
       
   165 	else
       
   166 		return 0;
       
   167 	}
       
   168 
       
   169 // global ordering object to be passed to RPointerArray InsertInOrderXXX and FindInOrder
       
   170 TLinearOrder<DIicBusChannel> EntryOrder(DIicBusController::OrderEntries);
       
   171 
       
   172 // Implementation for DIicBusController
       
   173 //
       
   174 
       
   175 TInt DIicBusController::Create()
       
   176 	{
       
   177 	TInt r=KErrNone;
       
   178 	iChanLock = new TSpinLock(TSpinLock::EOrderGenericIrqLow2);  // Semi-arbitrary, low priority value
       
   179 	iCaptLock = new TSpinLock(TSpinLock::EOrderGenericIrqLow2);  // Semi-arbitrary, low priority value
       
   180 	if((iChanLock == NULL)||(iCaptLock == NULL))
       
   181 		{
       
   182 		delete iChanLock;
       
   183 		delete iCaptLock;
       
   184 		r=KErrNoMemory;
       
   185 		}
       
   186 	return r;
       
   187 	}
       
   188 
       
   189 DIicBusController::~DIicBusController()
       
   190 	{
       
   191 #ifdef IIC_SIMULATED_PSL
       
   192 	for(TInt i=0; i<iChannelArray.Count(); i++)
       
   193 		{
       
   194 		DIicBusChannel* ptr=iChannelArray[i];
       
   195 		// Remove the channel from the array
       
   196 		iChannelArray.Remove(i);
       
   197 		// Delete the channel object
       
   198 		delete ptr;
       
   199 		};
       
   200 
       
   201 	iChannelArray.Reset();
       
   202 	delete iChanLock;
       
   203 	delete iCaptLock;
       
   204 #endif
       
   205 	}
       
   206 
       
   207 TInt DIicBusController::GetChanWriteAccess()
       
   208 	{
       
   209 	// Can only have one insertion or removal active at any one time
       
   210 	// Can not perform an insertion or removal while a read is in progress
       
   211 	// If either of the two above conditions exist, return KErrInUse
       
   212 	// Otherwise, set the flag to indicate that a write is in progress
       
   213 	// and return KErrNone.
       
   214 	TInt chanIntState=0;
       
   215 	chanIntState=__SPIN_LOCK_IRQSAVE(*iChanLock);
       
   216 	if(iChanRwFlags != 0)
       
   217 		{
       
   218 		__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   219 		return KErrInUse;
       
   220 		}
       
   221 	iChanRwFlags |= EWriteInProgress;
       
   222 	__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   223 	return KErrNone;
       
   224 	}
       
   225 
       
   226 void DIicBusController::FreeChanWriteAccess()
       
   227 	{
       
   228 	// If an insertion or removal is in progress, no other modifying operation
       
   229 	// can be active. Reads are also not permitted - so iChanRwFlags can only be
       
   230 	// EWriteInProgress.
       
   231 	__ASSERT_DEBUG(iChanRwFlags == EWriteInProgress, Kern::Fault(KIicPanic,__LINE__));
       
   232 	TInt chanIntState=0;
       
   233  	chanIntState=__SPIN_LOCK_IRQSAVE(*iChanLock);
       
   234  	iChanRwFlags &= ~EWriteInProgress;
       
   235  	__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   236 	}
       
   237 
       
   238 TInt DIicBusController::GetChanReadAccess()
       
   239 	{
       
   240 	// No reads are permitted while an insertion or removal is in progress
       
   241 	// If one of the above operations is in progress return KErrInUse
       
   242 	// Can have several concurrent reads at any one time - so increment
       
   243 	// the count of such operations as well as ensuring the flag is set to indicate
       
   244 	// a read is in progress
       
   245 	TInt chanIntState=0;
       
   246 	chanIntState=__SPIN_LOCK_IRQSAVE(*iChanLock);
       
   247 	if(iChanRwFlags == EWriteInProgress)
       
   248 		{
       
   249 		__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   250 		return KErrInUse;
       
   251 		}
       
   252 	__ASSERT_DEBUG(iChanRdCount!=0xFFFFFFFF, Kern::Fault(KIicPanic,__LINE__)); // Overflow
       
   253 	iChanRdCount++;
       
   254 	iChanRwFlags |= EReadInProgress;
       
   255 	__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   256 	return KErrNone;
       
   257 	}
       
   258 
       
   259 void DIicBusController::FreeChanReadAccess()
       
   260 	{
       
   261 	// No insertions or removals are permitted while a read is in progress
       
   262 	// so iChanRwFlags can only be EReadInProgress
       
   263 	// Multiple reads can be in progress concurrently, so the count must be decremented
       
   264 	TInt chanIntState=0;
       
   265 	chanIntState=__SPIN_LOCK_IRQSAVE(*iChanLock);
       
   266 	__ASSERT_DEBUG(iChanRwFlags == EReadInProgress, Kern::Fault(KIicPanic,__LINE__));
       
   267 	__ASSERT_DEBUG(iChanRdCount>0, Kern::Fault(KIicPanic,__LINE__));
       
   268 	iChanRdCount--;
       
   269 	if(iChanRdCount == 0)
       
   270 		iChanRwFlags &= ~EReadInProgress;
       
   271 	__SPIN_UNLOCK_IRQRESTORE(*iChanLock,chanIntState);
       
   272 	}
       
   273 
       
   274 TInt DIicBusController::RequestTypeSupported(const TInt aBusId, DIicBusChannelMaster* const aChannel)
       
   275 	{
       
   276 	TInt32 reqBusType;
       
   277 	reqBusType = GET_BUS_TYPE(aBusId);
       
   278 	__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RequestTypeSupported, BusType=0x%x\n", reqBusType));
       
   279 
       
   280 	if(reqBusType != aChannel->BusType())
       
   281 		{
       
   282 		return KErrNotSupported;
       
   283 		}
       
   284 
       
   285 	return KErrNone;
       
   286 	}
       
   287 
       
   288 
       
   289 EXPORT_C TInt DIicBusController::RegisterChannels(DIicBusChannel** aListChannels, TInt aNumberChannels)
       
   290 	{
       
   291 // To be used by Channel implementations to register a list of supported channels
       
   292     __KTRACE_OPT(KIIC, Kern::Printf("\nDIicBusController::RegisterChannels, aListChannels=0x%x, aNumberChannels=%d\n",aListChannels,aNumberChannels));
       
   293 	__ASSERT_DEBUG(aListChannels!=NULL, Kern::Fault(KIicPanic,__LINE__));
       
   294 
       
   295 	RPointerArray<DIicBusChannel>* chanArray = TheController->ChannelArray();
       
   296 
       
   297 #ifdef IIC_INSTRUMENTATION_MACRO
       
   298 	IIC_REGISTERCHANS_START_PIL_TRACE;
       
   299 #endif
       
   300 	// Get access to the channel pointer array - exit if it is currently being modfied
       
   301 	TInt r=KErrNone;
       
   302 	if((r=TheController->GetChanWriteAccess()) == KErrNone)
       
   303 		{
       
   304 #ifdef _DEBUG
       
   305 		__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RegisterChannels - On entry, iChannelArray ...\n"));
       
   306 		TheController->DumpChannelArray();
       
   307 #endif
       
   308 		// Loop for aNumberChannels	and write directly to the channel array
       
   309 		DIicBusChannel** chanIterator = aListChannels;
       
   310 		for(TInt iteration = 0; iteration < aNumberChannels; ++iteration, ++chanIterator)
       
   311 			{
       
   312 			DIicBusChannel* chanPtr = *chanIterator;
       
   313 			__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RegisterChannels - adding channel number %d\n",chanPtr->ChannelNumber()));
       
   314 			TInt r = chanArray->InsertInOrder(chanPtr,EntryOrder);
       
   315 			if(r!=KErrNone)
       
   316 				break;
       
   317 			}
       
   318 
       
   319 #ifdef _DEBUG
       
   320 		 __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RegisterChannels - On exit, iChannelArray ...\n"));
       
   321 		TheController->DumpChannelArray();
       
   322 #endif
       
   323 		TheController->FreeChanWriteAccess();
       
   324 		}
       
   325 	else
       
   326 		{
       
   327 		__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::GetChanWriteAccess returned %d\n",r));
       
   328 		}
       
   329 
       
   330 #ifdef IIC_INSTRUMENTATION_MACRO
       
   331 	IIC_REGISTERCHANS_END_PIL_TRACE;
       
   332 #endif
       
   333 	return r;
       
   334 	}
       
   335 
       
   336 
       
   337 EXPORT_C TInt DIicBusController::DeRegisterChannel(DIicBusChannel* aChannel)
       
   338 	{
       
   339 // To be used by Channel implementations to deregister a channel
       
   340     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::DeRegisterChannel, aChannel=0x%x\n",aChannel));
       
   341 	if(aChannel == NULL)
       
   342 		return KErrArgument;
       
   343 
       
   344 	RPointerArray<DIicBusChannel>* chanArray = TheController->ChannelArray();
       
   345 
       
   346 #ifdef IIC_INSTRUMENTATION_MACRO
       
   347 	IIC_DEREGISTERCHAN_START_PIL_TRACE;
       
   348 #endif
       
   349 	TInt r=KErrNone;
       
   350 	// Get access to the channel pointer array - exit if it is currently unavailable
       
   351 	// Gaining write access will prevent a client of a Master Channel from instigating a new QueueTransaction
       
   352 	// (or CancelTransaction), and it will obstruct a client of a Slave Channel in CaptureChannel.
       
   353 	if((r=TheController->GetChanWriteAccess())!=KErrNone)
       
   354 		return r;
       
   355 
       
   356 	// Check channel is registered
       
   357 	TInt chanIndex = chanArray->FindInOrder(aChannel,EntryOrder);
       
   358 	if(chanIndex<0)
       
   359 		{
       
   360 		TheController->FreeChanWriteAccess();
       
   361 		return KErrNotFound;
       
   362 		}
       
   363 
       
   364 #ifdef _DEBUG
       
   365     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::DeRegisterChannel - On entry, iChannelArray ...\n"));
       
   366 	TheController->DumpChannelArray();
       
   367 #endif
       
   368 
       
   369 	// Remove the channel from the array
       
   370 	// Note that this does not delete the channel object
       
   371 	chanArray->Remove(chanIndex);
       
   372 
       
   373 #ifdef _DEBUG
       
   374     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::DeRegisterChannel - On exit, iChannelArray ...\n"));
       
   375 	TheController->DumpChannelArray();
       
   376 #endif
       
   377 	TheController->FreeChanWriteAccess();
       
   378 
       
   379 #ifdef IIC_INSTRUMENTATION_MACRO
       
   380 	IIC_DEREGISTERCHAN_END_PIL_TRACE;
       
   381 #endif
       
   382 	return KErrNone;
       
   383 	}
       
   384 
       
   385 TInt DIicBusController::FindCapturedChanById(TCapturedChannel aCapturedChan, TInt& aIndex)
       
   386 	{
       
   387 	TInt index=0;
       
   388 	TInt r=KErrNotFound;
       
   389 	do
       
   390 		{
       
   391 		if(iCapturedChannels[index].iChannelId == aCapturedChan.iChannelId)
       
   392 			{
       
   393 			aIndex=index;
       
   394 			r=KErrNone;
       
   395 			}
       
   396 		index++;
       
   397 		} while ((index < KMaxNumCapturedChannels)&&(r == KErrNotFound));
       
   398 	return r;
       
   399 	}
       
   400 
       
   401 TInt DIicBusController::FindCapturedChan(TCapturedChannel aCapturedChan, TInt& aIndex)
       
   402 	{
       
   403 	TInt index=0;
       
   404 	TInt r=KErrNotFound;
       
   405 	do
       
   406 		{
       
   407 		if(iCapturedChannels[index] == aCapturedChan)
       
   408 			{
       
   409 			aIndex=index;
       
   410 			r=KErrNone;
       
   411 			}
       
   412 		index++;
       
   413 		} while ((index < KMaxNumCapturedChannels)&&(r == KErrNotFound));
       
   414 	return r;
       
   415 	}
       
   416 
       
   417 TInt DIicBusController::InsertCaptChanInArray(TCapturedChannel aCapturedChan)
       
   418 	{
       
   419 	__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::InsertCaptChanInArray \n"));
       
   420 	// Ensure the channel hasn't already been inserted in the array
       
   421 	// If found, fault the Kernel
       
   422 	TInt dumInt = 0;
       
   423 	TInt r=FindCapturedChan(aCapturedChan,dumInt);
       
   424 	__ASSERT_DEBUG(r!=KErrNone, Kern::Fault(KIicPanic,__LINE__));
       
   425 
       
   426 	// Loop the array and insert in the first available slot
       
   427 	// If no slots are available return KErrNotReady
       
   428 	TInt index=0;
       
   429 	TCapturedChannel emptyChan;
       
   430 	for(;index<KMaxNumCapturedChannels;++index)
       
   431 		{
       
   432 		if(iCapturedChannels[index] == emptyChan)
       
   433 			{
       
   434 			// Found a space
       
   435 			iCapturedChannels[index]=aCapturedChan;
       
   436 			break;
       
   437 			}
       
   438 		}
       
   439 	if(index>=KMaxNumCapturedChannels)
       
   440 		r = KErrNotReady;
       
   441 	return r;
       
   442 	}
       
   443 
       
   444 TInt DIicBusController::RemoveCaptChanFromArray(TCapturedChannel aCapturedChan)
       
   445 	{
       
   446 	// Remove the entry from the array
       
   447 	// If the entry is not present return KErrArgument
       
   448 	TInt index=-1;
       
   449 	TInt r=FindCapturedChan(aCapturedChan,index);
       
   450 	if((r!=KErrNone)||(index>=KMaxNumCapturedChannels))
       
   451 		return KErrArgument;
       
   452 	iCapturedChannels[index].iChanPtr=NULL;
       
   453 	iCapturedChannels[index].iChannelId=0;
       
   454 	return KErrNone;
       
   455 	}
       
   456 
       
   457 
       
   458 TInt DIicBusController::InstallCapturedChannel(const TInt aChannelId, const DIicBusChannelSlave* aChanPtr)
       
   459 	{
       
   460 #ifdef _DEBUG
       
   461     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::InstallCapturedChannel - On entry, iCapturedChannels ...\n"));
       
   462 	DumpCapturedChannels();
       
   463 #endif
       
   464 	TInt r=KErrNone;
       
   465 	TCapturedChannel capturedChan((TInt)aChannelId,(DIicBusChannelSlave*)aChanPtr);
       
   466 	// Because insertions are bounded by the size of the array and do not involve allocating
       
   467 	// or freeing memory, simply take the spinlock at the start of the operation and release at the end
       
   468 	TInt captIntState=__SPIN_LOCK_IRQSAVE(*iCaptLock);
       
   469 	r=InsertCaptChanInArray(capturedChan);
       
   470 	__SPIN_UNLOCK_IRQRESTORE(*iCaptLock,captIntState);
       
   471 	if(r!=KErrNone)
       
   472 		return r;
       
   473 
       
   474 #ifdef _DEBUG
       
   475     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::InstallCapturedChannel - On exit, iCapturedChannels ...\n"));
       
   476 	DumpCapturedChannels();
       
   477 #endif
       
   478 	return KErrNone;
       
   479 	}
       
   480 
       
   481 TInt DIicBusController::DeInstallCapturedChannel(const TInt aChannelId, const DIicBusChannelSlave* aChanPtr)
       
   482 	{
       
   483 #ifdef _DEBUG
       
   484     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::DeInstallCapturedChannel - On entry, iCapturedChannels ...\n"));
       
   485 	DumpCapturedChannels();
       
   486 #endif
       
   487 	TInt r = KErrNone;
       
   488 	TCapturedChannel capturedChan((TInt) aChannelId, (DIicBusChannelSlave*) aChanPtr);
       
   489 	// Because removals are bounded by the size of the array and do not involve allocating
       
   490 	// or freeing memory, simply take the spinlock at the start of the operation and release at the end
       
   491 	TInt captIntState = __SPIN_LOCK_IRQSAVE(*iCaptLock);
       
   492 	r = RemoveCaptChanFromArray(capturedChan);
       
   493 	__SPIN_UNLOCK_IRQRESTORE(*iCaptLock, captIntState);
       
   494 	if(r != KErrNone)
       
   495 		return r;
       
   496 
       
   497 #ifdef _DEBUG
       
   498     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::DeInstallCapturedChannel - On exit, iCapturedChannels ...\n"));
       
   499 	DumpCapturedChannels();
       
   500 #endif
       
   501 	return KErrNone;
       
   502 	}
       
   503 
       
   504 	// Master-side API
       
   505 TInt DIicBusController::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction)
       
   506 	{
       
   507 	__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::QueueTransaction, aBusId=0x%x,aTransaction=0x%x\n", aBusId, aTransaction));
       
   508 	if(!aTransaction)
       
   509 		{
       
   510 		return KErrArgument;
       
   511 		}
       
   512 
       
   513 	// Get a pointer to the channel
       
   514 	TInt dumInt = 0;
       
   515 	DIicBusChannel* chanPtr = NULL;
       
   516 	// Can only read the channel array if it is not currently being modified
       
   517 	TInt r = GetChanReadAccess();
       
   518 	if(r != KErrNone)
       
   519 		{
       
   520 		return r;
       
   521 		}
       
   522 	r = GetChanPtr(aBusId, dumInt, chanPtr);
       
   523 	if(r == KErrNone)
       
   524 		{
       
   525 		if(!chanPtr)
       
   526 			{
       
   527 			r = KErrArgument;
       
   528 			}
       
   529 		else
       
   530 			{
       
   531 			switch(chanPtr->ChannelType())
       
   532 				{
       
   533 				// QueueTransaction requests are only supported by channels in Master mode.
       
   534 				case DIicBusChannel::ESlave:
       
   535 					{
       
   536 					r = KErrNotSupported;
       
   537 					break;
       
   538 					}
       
   539 				// If the request is supported by the Master channel, send it to the channel for processing in its thread
       
   540 				case DIicBusChannel::EMasterSlave:
       
   541 					{
       
   542 					r = RequestTypeSupported(aBusId, ((DIicBusChannelMasterSlave*)chanPtr)->iMasterChannel);
       
   543 					if(r == KErrNone)
       
   544 						{
       
   545 						aTransaction->iBusId = aBusId;
       
   546 						r = (((DIicBusChannelMasterSlave*) chanPtr)->QueueTransaction(aTransaction));
       
   547 						}
       
   548 					break;
       
   549 					}
       
   550 				case DIicBusChannel::EMaster:
       
   551 					{
       
   552 					r = RequestTypeSupported(aBusId, (DIicBusChannelMaster*)chanPtr);
       
   553 					if(r == KErrNone)
       
   554 						{
       
   555 						aTransaction->iBusId = aBusId;
       
   556 						r = (((DIicBusChannelMaster*) chanPtr)->QueueTransaction(aTransaction));
       
   557 						}
       
   558 					break;
       
   559 					}
       
   560 				default:
       
   561 					{
       
   562 					r = KErrGeneral;
       
   563 					}
       
   564 				}
       
   565 			}
       
   566 		}
       
   567 	FreeChanReadAccess();
       
   568 	return r;
       
   569 	}
       
   570 
       
   571 TInt DIicBusController::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback* aCallback)
       
   572 	{
       
   573     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::QueueTransaction, aBusId=0x%x,aTransaction=0x%x,aCallback=0x%x\n",aBusId,aTransaction,aCallback));
       
   574 	if(!aTransaction || !aCallback)
       
   575 		{
       
   576 		return KErrArgument;
       
   577 		}
       
   578 
       
   579 	// Get a pointer to the channel
       
   580 	TInt dumInt = 0;
       
   581 	DIicBusChannel* chanPtr = NULL;
       
   582 	// Can only read the channel array if it is not currently being modified
       
   583 	TInt r = GetChanReadAccess();
       
   584 	if(r == KErrNone)
       
   585 		{
       
   586 		r = GetChanPtr(aBusId, dumInt, chanPtr);
       
   587 		if(r == KErrNone)
       
   588 			{
       
   589 			if(!chanPtr)
       
   590 				{
       
   591 				r = KErrArgument;
       
   592 				}
       
   593 			else
       
   594 				{
       
   595 				switch(chanPtr->ChannelType())
       
   596 					{
       
   597 					// QueueTransaction requests are only supported by channels in Master mode.
       
   598 					case DIicBusChannel::ESlave:
       
   599 						{
       
   600 						r = KErrNotSupported;
       
   601 						break;
       
   602 						}
       
   603 					// If the request is supported by the Master channel, send it to the channel for processing in its thread
       
   604 					case DIicBusChannel::EMasterSlave:
       
   605 						{
       
   606 						r = RequestTypeSupported(aBusId, ((DIicBusChannelMasterSlave*)chanPtr)->iMasterChannel);
       
   607 						if(r == KErrNone)
       
   608 							{
       
   609 							aTransaction->iBusId = aBusId;
       
   610 							r = (((DIicBusChannelMasterSlave*) chanPtr)->QueueTransaction(aTransaction, aCallback));
       
   611 							}
       
   612 						break;
       
   613 						}
       
   614 					case DIicBusChannel::EMaster:
       
   615 						{
       
   616 						r = RequestTypeSupported(aBusId, (DIicBusChannelMaster*)chanPtr);
       
   617 						if(r == KErrNone)
       
   618 							{
       
   619 							aTransaction->iBusId = aBusId;
       
   620 							r = (((DIicBusChannelMaster*) chanPtr)->QueueTransaction(aTransaction, aCallback));
       
   621 							}
       
   622 						break;
       
   623 						}
       
   624 					default:
       
   625 						{
       
   626 						r = KErrGeneral;
       
   627 						}
       
   628 					}
       
   629 				}
       
   630 			}
       
   631 		}
       
   632 	FreeChanReadAccess();
       
   633 	return r;
       
   634 	}
       
   635 
       
   636 
       
   637 TInt DIicBusController::GetChanPtr(const TInt aBusId, TInt &aIndex, DIicBusChannel*& aChan)
       
   638 	{
       
   639     __KTRACE_OPT(KIIC, 	Kern::Printf("DIicBusController::GetChanPtr, aBusId=0x%x\n",aBusId));
       
   640 
       
   641 	TInt32 chanId;
       
   642 	chanId = GET_CHAN_NUM(aBusId);
       
   643 
       
   644 	__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::GetChanPtr, chanId=0x%x\n", chanId));
       
   645 	DIicBusChannelSearcher searchChannel(DIicBusChannel::EMasterSlave, DIicBusChannel::ESccb, DIicBusChannel::EFullDuplex);
       
   646 	searchChannel.SetChannelNumber((TInt8)chanId);
       
   647 
       
   648 	TInt r = KErrNotFound;
       
   649 	aIndex = iChannelArray.FindInOrder(&searchChannel, EntryOrder);
       
   650 	if(aIndex >= 0)
       
   651 		{
       
   652 		aChan = iChannelArray[aIndex];
       
   653 		r = KErrNone;
       
   654 		}
       
   655 
       
   656 	__KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::GetChanPtr, chanPtr=0x%x, index=%d\n", aChan, aIndex));
       
   657 	return r;
       
   658 	}
       
   659 
       
   660 
       
   661 TInt DIicBusController::CancelTransaction(TInt aBusId, TIicBusTransaction* aTransaction)
       
   662 	{
       
   663     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::CancelTransaction, aBusId=0x%x,aTransaction=0x%x\n", aBusId, aTransaction));
       
   664 	if(!aTransaction)
       
   665 		{
       
   666 		return KErrArgument;
       
   667 		}
       
   668 
       
   669 	// Get the channel
       
   670 	TInt dumInt = 0;
       
   671 	DIicBusChannel* chanPtr = NULL;
       
   672 
       
   673 	// Can only read the channel array if it is not currently being modified
       
   674 	TInt r = GetChanReadAccess();
       
   675 	if(r == KErrNone)
       
   676 		{
       
   677 		r = GetChanPtr(aBusId, dumInt, chanPtr);
       
   678 		if(r == KErrNone)
       
   679 			{
       
   680 			if(!chanPtr)
       
   681 				{
       
   682 				r = KErrArgument;
       
   683 				}
       
   684 			else
       
   685 				{
       
   686 				// QueueTransaction requests are only supported by channels in Master mode.
       
   687 				switch(chanPtr->ChannelType())
       
   688 					{
       
   689 					case DIicBusChannel::ESlave:
       
   690 						{
       
   691 						r = KErrNotSupported;
       
   692 						break;
       
   693 						}
       
   694 					case DIicBusChannel::EMasterSlave:
       
   695 						{
       
   696 						r = RequestTypeSupported(aBusId, ((DIicBusChannelMasterSlave*)chanPtr)->iMasterChannel);
       
   697 						if(r == KErrNone)
       
   698 							{
       
   699 							r = (((DIicBusChannelMasterSlave*) chanPtr)->CancelTransaction(aTransaction));
       
   700 							}
       
   701 						break;
       
   702 						}
       
   703 					case DIicBusChannel::EMaster:
       
   704 						{
       
   705 						r = RequestTypeSupported(aBusId, (DIicBusChannelMaster*)chanPtr);
       
   706 						if(r == KErrNone)
       
   707 							{
       
   708 							r = (((DIicBusChannelMaster*) chanPtr)->CancelTransaction(aTransaction));
       
   709 							}
       
   710 						break;
       
   711 						}
       
   712 					default:
       
   713 						{
       
   714 						r = KErrGeneral;
       
   715 						}
       
   716 					}
       
   717 				}
       
   718 			}
       
   719 		}
       
   720 	FreeChanReadAccess();
       
   721 	return r;
       
   722 	}
       
   723 
       
   724 	// Slave-side API
       
   725 TInt DIicBusController::CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch)
       
   726 	{
       
   727 	// Check that that aCallback!=NULL and aConfigHdr!=NULL - if not, return KErrArgument
       
   728 	if(!aCallback || !aConfigHdr)
       
   729 		{
       
   730 		return KErrArgument;
       
   731 		}
       
   732 
       
   733 	// Get the channel
       
   734 	TInt chanIndex = 0;
       
   735 	DIicBusChannel* chanPtr = NULL;
       
   736 
       
   737 	// Can only read the channel array if it is not currently being modified
       
   738 	TInt r = GetChanReadAccess();
       
   739 	if(r == KErrNone)
       
   740 		{
       
   741 		r = GetChanPtr(aBusId, chanIndex, chanPtr);
       
   742 		if(r == KErrNone)
       
   743 			{
       
   744 			if(!chanPtr)
       
   745 				{
       
   746 				r = KErrArgument;
       
   747 				}
       
   748 			else
       
   749 				{
       
   750 				DIicBusChannelSlave* slaveChanPtr = NULL;
       
   751 				switch(chanPtr->ChannelType())
       
   752 					{
       
   753 					// CaptureChannel requests are only supported by channels in Slave mode.
       
   754 					case DIicBusChannel::EMaster:
       
   755 						{
       
   756 						r = KErrNotSupported;
       
   757 						break;
       
   758 						}
       
   759 					case DIicBusChannel::EMasterSlave:
       
   760 						{
       
   761 						slaveChanPtr = ((DIicBusChannelMasterSlave*) chanPtr)->iSlaveChannel;
       
   762 						__ASSERT_DEBUG(slaveChanPtr!=NULL, Kern::Fault(KIicPanic,__LINE__)); // MasterSlave channel should have a valid Slave channel
       
   763 						// Send the request to the channel
       
   764 						slaveChanPtr->iController = this;
       
   765 						r = ((DIicBusChannelMasterSlave*) chanPtr)->CaptureChannel(aConfigHdr, aCallback, aChannelId, aAsynch);
       
   766 						break;
       
   767 						}
       
   768 					case DIicBusChannel::ESlave:
       
   769 						{
       
   770 						slaveChanPtr = (DIicBusChannelSlave*) chanPtr; // chanPtr is non-NULL
       
   771 						// Send the request to the channel
       
   772 						slaveChanPtr->iController = this;
       
   773 						r = (slaveChanPtr->CaptureChannel(aConfigHdr, aCallback, aChannelId, aAsynch));
       
   774 						break;
       
   775 						}
       
   776 					default:
       
   777 						{
       
   778 						r = KErrArgument;
       
   779 						}
       
   780 					}
       
   781 				// For synchronous capture, if successful then install the channel
       
   782 				if(r == KErrNone && slaveChanPtr)
       
   783 					{
       
   784 					if(!aAsynch)
       
   785 						{
       
   786 						InstallCapturedChannel(aChannelId, slaveChanPtr);
       
   787 						}
       
   788 					}
       
   789 				}
       
   790 			}
       
   791 		}
       
   792 	FreeChanReadAccess();
       
   793 	return r;
       
   794 	}
       
   795 
       
   796 
       
   797 TInt DIicBusController::GetSlaveChanPtr(TInt aChannelId, DIicBusChannelSlave*& aSlaveChanPtr)
       
   798 	{
       
   799 	TInt r=KErrNone;
       
   800 	// Check that the channelID is recognised
       
   801 	TCapturedChannel capturedChan(aChannelId,NULL);
       
   802 	TInt chanIndex=-1;
       
   803 	// Ensure the array of captured channels will not be modified before it has been searched
       
   804 	// Because searches are bounded by the size of the array and do not involve allocating
       
   805 	// or freeing memory, simply take the spinlock at the start of the operation and release at the end
       
   806 	TInt captIntState=__SPIN_LOCK_IRQSAVE(*iCaptLock);
       
   807 	r=FindCapturedChanById(capturedChan, chanIndex);
       
   808 	if((chanIndex < 0)||(r == KErrNotFound))
       
   809 		r=KErrArgument;
       
   810 	else
       
   811 		aSlaveChanPtr = (DIicBusChannelSlave*)(iCapturedChannels[chanIndex].iChanPtr);
       
   812 	__SPIN_UNLOCK_IRQRESTORE(*iCaptLock,captIntState);
       
   813 
       
   814 	__ASSERT_DEBUG(aSlaveChanPtr!=NULL, Kern::Fault(KIicPanic,__LINE__));
       
   815 	return r;
       
   816 	}
       
   817 
       
   818 
       
   819 TInt DIicBusController::ReleaseChannel(TInt aChannelId)
       
   820 	{
       
   821     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::ReleaseChannel, channelID = 0x%x \n",aChannelId));
       
   822 	TInt r = KErrNone;
       
   823 	DIicBusChannel* chanPtr = NULL;
       
   824 	
       
   825 	// Get the pointer to the Slave Channel
       
   826 	DIicBusChannelSlave* slaveChanPtr = NULL;
       
   827 	if((r = GetSlaveChanPtr(aChannelId, slaveChanPtr)) != KErrNone)
       
   828 		return r;
       
   829 		
       
   830 	DIicBusChannelSearcher searchChannel(DIicBusChannel::EMasterSlave, DIicBusChannel::ESccb, DIicBusChannel::EFullDuplex);
       
   831 	searchChannel.SetChannelNumber(slaveChanPtr->ChannelNumber());
       
   832 
       
   833 	TInt dumIndex = iChannelArray.FindInOrder(&searchChannel, EntryOrder);
       
   834 	if(dumIndex < 0)
       
   835 		{
       
   836 		return KErrNotFound;
       
   837 		}
       
   838 	chanPtr = iChannelArray[dumIndex];
       
   839 
       
   840 	__ASSERT_DEBUG(chanPtr!=NULL, Kern::Fault(KIicPanic,__LINE__));
       
   841 
       
   842 	//if it is the masterslave channel, then call the masterslave's RelaseChannel
       
   843 	// which will call the slave channel's ReleaseChannel internally
       
   844 	if(chanPtr->ChannelType() == DIicBusChannel::EMasterSlave)
       
   845 		r = ((DIicBusChannelMasterSlave*)chanPtr)->ReleaseChannel();
       
   846 	else // Call the slave only ReleaseChannel
       
   847 		r = slaveChanPtr->ReleaseChannel();
       
   848 	
       
   849 	// In either case de-install the captured slave channel
       
   850 	if(r == KErrNone)
       
   851 		{
       
   852 		r = DeInstallCapturedChannel(aChannelId, slaveChanPtr);
       
   853 		}
       
   854 
       
   855 	// No need to unset iController - there is only one IIC Controller
       
   856 	return r;
       
   857 	}
       
   858 
       
   859 
       
   860 TInt DIicBusController::RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   861 	{
       
   862     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RegisterRxBuffer, channelID=0x%x,aRxBuffer=0x%x,aBufGranularity=0x%x,aNumWords=0x%x,aOffset=0x%x \n",aChannelId,(TInt)&aRxBuffer,aBufGranularity,aNumWords,aOffset));
       
   863 
       
   864     // Acquire the pointer to the Slave Channel
       
   865 	DIicBusChannelSlave* slaveChanPtr = NULL;
       
   866 	TInt r = GetSlaveChanPtr(aChannelId, slaveChanPtr);
       
   867 	if(r != KErrNone)
       
   868 		{
       
   869 		return r;
       
   870 		}
       
   871 
       
   872 	// Instigate the channel functionality
       
   873 	return(slaveChanPtr->RegisterRxBuffer(aRxBuffer,aBufGranularity,aNumWords,aOffset));
       
   874 	}
       
   875 
       
   876 TInt DIicBusController::RegisterTxBuffer(TInt aChannelId, TPtr8 aTxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset)
       
   877 	{
       
   878     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::RegisterTxBuffer, channelID=0x%x,aTxBuffer=0x%x,aBufGranularity=0x%x,aNumWords=0x%x,aOffset=0x%x \n",aChannelId,(TInt)&aTxBuffer,aBufGranularity,aNumWords,aOffset));
       
   879 
       
   880 	// Acquire the pointer to the Slave Channel
       
   881 	DIicBusChannelSlave* slaveChanPtr = NULL;
       
   882 	TInt r = GetSlaveChanPtr(aChannelId, slaveChanPtr);
       
   883 	if(r != KErrNone)
       
   884 		{
       
   885 		return r;
       
   886 		}
       
   887 
       
   888 	// Instigate the channel functionality
       
   889 	return (slaveChanPtr->RegisterTxBuffer(aTxBuffer, aBufGranularity, aNumWords, aOffset));
       
   890 	}
       
   891 
       
   892 
       
   893 TInt DIicBusController::SetNotificationTrigger(TInt aChannelId, TInt aTrigger)
       
   894 	{
       
   895     __KTRACE_OPT(KIIC, Kern::Printf("DIicBusController::SetNotificationTrigger - for aChannelId=0x%x, aTrigger=0x%x\n",aChannelId,aTrigger));
       
   896 	// Acquire the pointer to the Slave Channel
       
   897 	DIicBusChannelSlave* slaveChanPtr = NULL;
       
   898 	TInt r = GetSlaveChanPtr(aChannelId, slaveChanPtr);
       
   899 	if( r != KErrNone)
       
   900 		{
       
   901 		return r;
       
   902 		}
       
   903 
       
   904 	// Instigate the channel functionality
       
   905 	return(slaveChanPtr->SetNotificationTrigger(aTrigger));
       
   906 	}
       
   907 
       
   908 
       
   909 TInt DIicBusController::StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, TAny* aParam2)
       
   910 	{
       
   911 //		The IIC controller and channel classes are generic, and can serve many differing client and
       
   912 //		bus implementations. If a client and bus make use of specific functionality that is not
       
   913 //		common to other bus types, it makes sense to provide only the minimum-required support in the
       
   914 //		generic code. Here, the channel identifier is checked but all other parameters are passed
       
   915 //		directly to the bus implementation channel for processing; if the channel does not provide
       
   916 //		StaticExtension implementation, the generic DIicBusChannel::StaticExtension method is invoked.
       
   917 
       
   918 #ifdef IIC_INSTRUMENTATION_MACRO
       
   919 	if((aFunction & KControlIoMask) == KMasterSlaveControlIo)
       
   920 		{
       
   921 		IIC_MSSTATEXT_START_PIL_TRACE
       
   922 		}
       
   923 	else if((aFunction & KControlIoMask) == KMasterControlIo)
       
   924 		{
       
   925 		IIC_MSTATEXT_START_PIL_TRACE
       
   926 		}
       
   927 	else if((aFunction & KControlIoMask) == KSlaveControlIo)
       
   928 		{
       
   929 		IIC_SSTATEXT_START_PIL_TRACE
       
   930 		}
       
   931 //	else - Unexpected value - just pass silently to the PSL ...
       
   932 #endif
       
   933 
       
   934 	// Get the channel
       
   935 	TInt dumInt = 0;
       
   936 	DIicBusChannel* chanPtr = NULL;
       
   937 	// Can only read the channel array if it is not currently being modified
       
   938 	TInt r = GetChanReadAccess();
       
   939 	if(r == KErrNone)
       
   940 		{
       
   941 		r = GetChanPtr(aId, dumInt, chanPtr);
       
   942 		if(r == KErrNone)
       
   943 			{
       
   944 			if(!chanPtr)
       
   945 				{
       
   946 				r = KErrArgument;
       
   947 				}
       
   948 			else
       
   949 				{
       
   950 				r = chanPtr->StaticExtension(aFunction, aParam1, aParam2);
       
   951 				}
       
   952 			}
       
   953 		}
       
   954 
       
   955 #ifdef IIC_INSTRUMENTATION_MACRO
       
   956 	if((aFunction & KControlIoMask) == KMasterSlaveControlIo)
       
   957 		{
       
   958 		IIC_MSSTATEXT_START_PIL_TRACE
       
   959 		}
       
   960 	else if((aFunction & KControlIoMask) == KMasterControlIo)
       
   961 		{
       
   962 		IIC_MSTATEXT_START_PIL_TRACE
       
   963 		}
       
   964 	else if((aFunction & KControlIoMask) == KSlaveControlIo)
       
   965 		{
       
   966 		IIC_SSTATEXT_START_PIL_TRACE
       
   967 		}
       
   968 //	else	... do nothing
       
   969 #endif
       
   970 	FreeChanReadAccess();
       
   971 	return r;
       
   972 	}
       
   973 
       
   974 
       
   975 #ifdef _DEBUG
       
   976 
       
   977 void DIicBusController::DumpCapturedChannels()
       
   978 	{
       
   979 	// Print iCapturedChannels ...
       
   980 	TInt count=0;
       
   981 	TInt i=0;
       
   982 	TCapturedChannel emptyChan;
       
   983 	for(;i<KMaxNumCapturedChannels;++i)
       
   984 		{
       
   985 		if(iCapturedChannels[i] == emptyChan)
       
   986 			continue;
       
   987 		++count;
       
   988 		}
       
   989 
       
   990 	i = 0;
       
   991     __KTRACE_OPT(KIIC, Kern::Printf("	- Count gave %d\n",count));
       
   992 	for(;i<KMaxNumCapturedChannels;++i)
       
   993 		{
       
   994 		if(iCapturedChannels[i] == emptyChan)
       
   995 			continue;
       
   996 		DIicBusChannel* ptr=(DIicBusChannel*)(iCapturedChannels[i]).iChanPtr;
       
   997 	    __KTRACE_OPT(KIIC, Kern::Printf("	- ptr %d=0x%x\n",i,ptr));
       
   998 		ptr->StaticExtension(KCtrlIoDumpChan,0,0);
       
   999 		};
       
  1000 	}
       
  1001 
       
  1002 void DIicBusController::DumpChannelArray()
       
  1003 	{
       
  1004 	TInt i = 0;
       
  1005 	__KTRACE_OPT(KIIC, Kern::Printf("\nDIicBusController::DumpChannelArray\n"));
       
  1006     __KTRACE_OPT(KIIC, Kern::Printf("	- Count gave %d\n",iChannelArray.Count()));
       
  1007 	for(i=0; i<iChannelArray.Count(); i++)
       
  1008 		{
       
  1009 		DIicBusChannel* ptr=iChannelArray[i];
       
  1010 	    __KTRACE_OPT(KIIC, Kern::Printf("	- ptr %d=0x%x\n",i,ptr));
       
  1011 		ptr->StaticExtension(KCtrlIoDumpChan,0,0);
       
  1012 		};
       
  1013 	}
       
  1014 
       
  1015 #endif
       
  1016 
       
  1017 #ifdef IIC_SIMULATED_PSL
       
  1018 TVersion DIicPdd::VersionRequired()
       
  1019 	{
       
  1020 	const TInt KIicMajorVersionNumber=1;
       
  1021 	const TInt KIicMinorVersionNumber=0;
       
  1022 	const TInt KIicBuildVersionNumber=KE32BuildVersionNumber;
       
  1023 	return TVersion(KIicMajorVersionNumber,KIicMinorVersionNumber,KIicBuildVersionNumber);
       
  1024 	}
       
  1025 
       
  1026 /** Factory class constructor */
       
  1027 DIicPdd::DIicPdd()
       
  1028 	{
       
  1029     iVersion = DIicPdd::VersionRequired();
       
  1030 	}
       
  1031 
       
  1032 DIicPdd::~DIicPdd()
       
  1033 	{
       
  1034 	delete TheController;
       
  1035 	}
       
  1036 
       
  1037 TInt DIicPdd::Install()
       
  1038     {
       
  1039     return(SetName(&KPddName));
       
  1040     }
       
  1041 
       
  1042 /**  Called by the kernel's device driver framework to create a Physical Channel. */
       
  1043 TInt DIicPdd::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
       
  1044     {
       
  1045     return KErrNone;
       
  1046     }
       
  1047 
       
  1048 /**  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
       
  1049 TInt DIicPdd::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
  1050     {
       
  1051    	if (!Kern::QueryVersionSupported(DIicPdd::VersionRequired(),aVer))
       
  1052 		return(KErrNotSupported);
       
  1053     return KErrNone;
       
  1054     }
       
  1055 
       
  1056 /** Return the driver capabilities */
       
  1057 void DIicPdd::GetCaps(TDes8& aDes) const
       
  1058     {
       
  1059 	// Create a capabilities object
       
  1060 	TCaps caps;
       
  1061 	caps.iVersion = iVersion;
       
  1062 	// Zero the buffer
       
  1063 	TInt maxLen = aDes.MaxLength();
       
  1064 	aDes.FillZ(maxLen);
       
  1065 	// Copy cpabilities
       
  1066 	TInt size=sizeof(caps);
       
  1067 	if(size>maxLen)
       
  1068 	   size=maxLen;
       
  1069 	aDes.Copy((TUint8*)&caps,size);
       
  1070     }
       
  1071 #endif
       
  1072 
       
  1073 #ifndef IIC_SIMULATED_PSL
       
  1074 // Client interface entry point
       
  1075 DECLARE_EXTENSION_WITH_PRIORITY(KExtensionMaximumPriority-1)	// highest priority after Resource Manager
       
  1076 	{
       
  1077 	TheController = new DIicBusController;
       
  1078 	if(!TheController)
       
  1079 		return KErrNoMemory;
       
  1080 	TInt r=TheController->Create();
       
  1081 	return r;
       
  1082 	}
       
  1083 #else
       
  1084 static DIicPdd* TheIicPdd;
       
  1085 
       
  1086 DECLARE_STANDARD_PDD()
       
  1087 	{
       
  1088 	TheController = new DIicBusController;
       
  1089 	if(!TheController)
       
  1090 		return NULL;
       
  1091 	TInt r = TheController->Create();
       
  1092 	if(r == KErrNone)
       
  1093 		{
       
  1094 		TheIicPdd = new DIicPdd;
       
  1095 		if(TheIicPdd)
       
  1096 			return TheIicPdd;
       
  1097 		}
       
  1098 	
       
  1099 	delete TheController; 
       
  1100 	return NULL;
       
  1101 	}
       
  1102 #endif
       
  1103 
       
  1104 
       
  1105