88 } |
88 } |
89 |
89 |
90 class DIicClientChan : public DBase |
90 class DIicClientChan : public DBase |
91 { |
91 { |
92 public: |
92 public: |
93 DIicClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TUint8 aChanType):iChan(aChan),iChanNumber(aChanNum),iChanType(aChanType){}; |
93 DIicClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TUint8 aChanType):iChanNumber(aChanNum),iChanType(aChanType),iChan(aChan){}; |
94 ~DIicClientChan(); |
94 ~DIicClientChan(); |
95 TInt GetChanNum()const {return iChanNumber;}; |
95 TInt GetChanNum()const {return iChanNumber;}; |
96 TUint8 GetChanType()const {return iChanType;}; |
96 TUint8 GetChanType()const {return iChanType;}; |
97 DIicBusChannel* GetChannelPtr(){return iChan;}; |
97 DIicBusChannel* GetChannelPtr(){return iChan;}; |
98 inline DIicClientChan& operator=(DIicClientChan& aChan) {iChanNumber=aChan.iChanNumber; iChanType=aChan.iChanType; iChan=aChan.iChan; return *this;}; |
98 inline DIicClientChan& operator=(DIicClientChan& aChan) {iChanNumber=aChan.iChanNumber; iChanType=aChan.iChanType; iChan=aChan.iChan; return *this;}; |
110 |
110 |
111 #endif /*STANDALONE_CHANNEL*/ |
111 #endif /*STANDALONE_CHANNEL*/ |
112 |
112 |
113 |
113 |
114 #ifdef STANDALONE_CHANNEL |
114 #ifdef STANDALONE_CHANNEL |
|
115 #ifdef IIC_STUBS |
|
116 _LIT(KLddRootName,"iic_client_stubs"); |
|
117 #else |
115 _LIT(KLddRootName,"iic_client_ctrless"); |
118 _LIT(KLddRootName,"iic_client_ctrless"); |
116 #else |
119 #endif/*IIC_STUBS*/ |
|
120 |
|
121 #else/*STANDALONE_CHANNEL*/ |
117 _LIT(KLddRootName,"iic_client"); |
122 _LIT(KLddRootName,"iic_client"); |
118 #endif |
123 #endif |
119 _LIT(KIicClientThreadName,"IicClientLddThread"); |
124 _LIT(KIicClientThreadName,"IicClientLddThread"); |
120 |
125 |
121 struct TCapsIicClient |
126 struct TCapsIicClient |
401 TInt QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback *aCallback=NULL); |
406 TInt QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback *aCallback=NULL); |
402 TInt CancelTransaction(TInt aBusId, TIicBusTransaction* aTransaction); |
407 TInt CancelTransaction(TInt aBusId, TIicBusTransaction* aTransaction); |
403 TInt StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, TAny* aParam2); |
408 TInt StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, TAny* aParam2); |
404 TInt CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch=NULL); |
409 TInt CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch=NULL); |
405 TInt ReleaseChannel(TInt aChannelId); |
410 TInt ReleaseChannel(TInt aChannelId); |
|
411 TInt Spare1(TInt aBusId); |
406 public: |
412 public: |
407 inline void Lock() {Kern::MutexWait(*iArrayMutex);} |
413 inline void Lock() {Kern::MutexWait(*iArrayMutex);} |
408 inline void Unlock() {Kern::MutexSignal(*iArrayMutex);} |
414 inline void Unlock() {Kern::MutexSignal(*iArrayMutex);} |
409 inline void GetWriteAccess() {Kern::SemaphoreWait(*iChanArrWrtSem);} // aNTicks not specified = wait forever |
415 inline void GetWriteAccess() {Kern::SemaphoreWait(*iChanArrWrtSem);} // aNTicks not specified = wait forever |
410 inline void FreeWriteAccess() {Kern::SemaphoreSignal(*iChanArrWrtSem);} |
416 inline void FreeWriteAccess() {Kern::SemaphoreSignal(*iChanArrWrtSem);} |
497 |
503 |
498 DDeviceIicClient::DDeviceIicClient() |
504 DDeviceIicClient::DDeviceIicClient() |
499 // Constructor |
505 // Constructor |
500 { |
506 { |
501 CLIENT_PRINT(("> DDeviceIicClient::DDeviceIicClient()")); |
507 CLIENT_PRINT(("> DDeviceIicClient::DDeviceIicClient()")); |
502 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::DDeviceIicClient()")); |
508 __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::DDeviceIicClient()")); |
503 iParseMask=0; // No info, no PDD, no Units |
509 iParseMask=0; // No info, no PDD, no Units |
504 iUnitsMask=0; |
510 iUnitsMask=0; |
505 iVersion=TVersion(KIicClientMajorVersionNumber, |
511 iVersion=TVersion(KIicClientMajorVersionNumber, |
506 KIicClientMinorVersionNumber, |
512 KIicClientMinorVersionNumber, |
507 KIicClientBuildVersionNumber); |
513 KIicClientBuildVersionNumber); |
527 #endif /*STANDALONE_CHANNEL*/ |
533 #endif /*STANDALONE_CHANNEL*/ |
528 |
534 |
529 DDeviceIicClient::~DDeviceIicClient() |
535 DDeviceIicClient::~DDeviceIicClient() |
530 { |
536 { |
531 CLIENT_PRINT(("> DDeviceIicClient::~DDeviceIicClient()")); |
537 CLIENT_PRINT(("> DDeviceIicClient::~DDeviceIicClient()")); |
532 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::~DDeviceIicClient()")); |
538 __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::~DDeviceIicClient()")); |
533 #ifdef STANDALONE_CHANNEL |
539 #ifdef STANDALONE_CHANNEL |
534 //For Standalone Channel, the client is responsible for channel destroy |
540 //For Standalone Channel, the client is responsible for channel destroy |
535 ChannelArray.ResetAndDestroy(); |
541 ChannelArray.ResetAndDestroy(); |
536 #endif |
542 #endif |
537 } |
543 } |
538 |
544 |
539 TInt DDeviceIicClient::Install() |
545 TInt DDeviceIicClient::Install() |
540 // Install the device driver. |
546 // Install the device driver. |
541 { |
547 { |
542 CLIENT_PRINT(("> DDeviceIicClient::Install()")); |
548 CLIENT_PRINT(("> DDeviceIicClient::Install()")); |
543 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::Install()")); |
549 __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::Install()")); |
544 return(SetName(&KLddRootName)); |
550 return(SetName(&KLddRootName)); |
545 } |
551 } |
546 |
552 |
547 // Auxiliary functions for ordering entries in the array of TTransStatusPair pointers |
553 // Auxiliary functions for ordering entries in the array of TTransStatusPair pointers |
548 // The first is to enable searching by Transaction (used by the callback) |
554 // The first is to enable searching by Transaction (used by the callback) |
761 //If in STANDALONE_CHANNEL mode, the client creates a list of channels |
767 //If in STANDALONE_CHANNEL mode, the client creates a list of channels |
762 #ifdef STANDALONE_CHANNEL |
768 #ifdef STANDALONE_CHANNEL |
763 DIicClientChan* aClientChan; |
769 DIicClientChan* aClientChan; |
764 TInt r = KErrNone; |
770 TInt r = KErrNone; |
765 DIicBusChannel *chan = NULL, *chanM = NULL, *chanS = NULL; |
771 DIicBusChannel *chan = NULL, *chanM = NULL, *chanS = NULL; |
766 TInt i; |
772 TUint i; |
767 for(i=0; i<NUM_CHANNELS_SPI; i++) |
773 for(i=0; i<NUM_CHANNELS_SPI; i++) |
768 { |
774 { |
769 CLIENT_PRINT(("\n")); |
775 CLIENT_PRINT(("\n")); |
770 #if defined(MASTER_MODE) |
776 #if defined(MASTER_MODE) |
771 if(CHANNEL_TYPE_SPI(i) == (DIicBusChannel::EMaster)) |
777 if(CHANNEL_TYPE_SPI(i) == (DIicBusChannel::EMaster)) |
1017 |
1023 |
1018 DChannelIicClient::~DChannelIicClient() |
1024 DChannelIicClient::~DChannelIicClient() |
1019 // Destructor |
1025 // Destructor |
1020 { |
1026 { |
1021 CLIENT_PRINT(("> DChannelIicClient::~DChannelIicClient()")); |
1027 CLIENT_PRINT(("> DChannelIicClient::~DChannelIicClient()")); |
1022 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelIicClient::~DChannelIicClient()")); |
1028 __KTRACE_OPT(KIIC, Kern::Printf("> DChannelIicClient::~DChannelIicClient()")); |
1023 delete iNotif; |
1029 delete iNotif; |
1024 iArrayMutex->Close(NULL); |
1030 iArrayMutex->Close(NULL); |
1025 iChanArrWrtSem->Close(NULL); |
1031 iChanArrWrtSem->Close(NULL); |
1026 iDfcQue->Destroy(); |
1032 iDfcQue->Destroy(); |
1027 // decrement the DThread's reference count |
1033 // decrement the DThread's reference count |
1322 iCapturedChannel.iChannelId = 0; |
1328 iCapturedChannel.iChannelId = 0; |
1323 #endif |
1329 #endif |
1324 return r; |
1330 return r; |
1325 } |
1331 } |
1326 |
1332 |
|
1333 //this function is added for improving the code coverage of IIC. |
|
1334 //Spare1 is a placeholder for future expansion, and so returns KErrNotSupported. |
|
1335 #ifdef STANDALONE_CHANNEL |
|
1336 TInt DChannelIicClient::Spare1(TInt aBusId) |
|
1337 { |
|
1338 TInt r = KErrNone; |
|
1339 |
|
1340 TInt chanIndex = 0; |
|
1341 DIicClientChan* chanPtr = NULL; |
|
1342 if(r == KErrNone) |
|
1343 { |
|
1344 r = GetChanPtr(aBusId, chanIndex, chanPtr); |
|
1345 if(r == KErrNone) |
|
1346 { |
|
1347 if(!chanPtr) |
|
1348 { |
|
1349 r = KErrArgument; |
|
1350 } |
|
1351 else |
|
1352 { |
|
1353 switch(chanPtr->GetChanType()) |
|
1354 { |
|
1355 case DIicBusChannel::EMaster: |
|
1356 { |
|
1357 r = ((DIicBusChannelMaster*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); |
|
1358 break; |
|
1359 } |
|
1360 case DIicBusChannel::EMasterSlave: |
|
1361 { |
|
1362 r = KErrNotSupported; |
|
1363 break; |
|
1364 } |
|
1365 case DIicBusChannel::ESlave: |
|
1366 { |
|
1367 r = ((DIicBusChannelSlave*)(chanPtr->GetChannelPtr()))->Spare1(0,NULL,NULL); |
|
1368 break; |
|
1369 } |
|
1370 default: |
|
1371 { |
|
1372 r = KErrArgument; |
|
1373 } |
|
1374 } |
|
1375 } |
|
1376 } |
|
1377 } |
|
1378 return r; |
|
1379 } |
|
1380 #endif |
|
1381 |
|
1382 #ifndef IIC_STUBS |
1327 void DChannelIicClient::DoCancel(TInt aMask) |
1383 void DChannelIicClient::DoCancel(TInt aMask) |
1328 { |
1384 { |
1329 // Cancel an outstanding request. |
1385 // Cancel an outstanding request. |
1330 CLIENT_PRINT(("DChannelIicClient::DoCancel invoked with aMask=0x%x\n", aMask)); |
1386 CLIENT_PRINT(("DChannelIicClient::DoCancel invoked with aMask=0x%x\n", aMask)); |
1331 |
1387 |
1404 delete cbPair; |
1460 delete cbPair; |
1405 delete searchPair; |
1461 delete searchPair; |
1406 |
1462 |
1407 return; |
1463 return; |
1408 } |
1464 } |
1409 |
1465 #else/*IIC_STUBS*/ |
|
1466 //should only be called in IIC_STUBS mode |
|
1467 //DoCancel is used to cancel an asynchronous request which is still waiting in the queue and |
|
1468 //has not yet been handled by IIC. |
|
1469 //In the stub test, QueueTransaction should always return a KErrNotSupported error code |
|
1470 //So we pretend there is an request waiting in the queue that can be cancelled by calling DoCancel. |
|
1471 void DChannelIicClient::DoCancel(TInt aMask) |
|
1472 { |
|
1473 // Cancel an outstanding request. |
|
1474 CLIENT_PRINT(("DChannelIicClient::DoCancel invoked with aMask=0x%x\n", aMask)); |
|
1475 |
|
1476 // inline void CancelAsyncOperation(TRequestStatus* aStatus, TInt aBusId) {TInt* parms[2]; parms[0]=(TInt*)aStatus; parms[1]=(TInt*)aBusId;DoCancel((TInt)&parms[0]);} |
|
1477 // aMask has the address on TInt* parms[2] |
|
1478 // parms[0] = TRequestStatus pointer |
|
1479 // parms[1] = Bus Identifier |
|
1480 TInt* parms[2]; |
|
1481 TInt r=Kern::ThreadRawRead(iClient,(TAny*)aMask,&(parms[0]),2*sizeof(TInt*)); |
|
1482 if(r!=KErrNone) |
|
1483 { |
|
1484 CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't read parms[]\n")); |
|
1485 return; // Can't proceed if can't access request parameters |
|
1486 } |
|
1487 CLIENT_PRINT(("DChannelIicClient::DoCancel - TRequestStatus 0x%x, BusID = 0x%x\n",parms[0],parms[1])); |
|
1488 TRequestStatus* status= (TRequestStatus*)(parms[0]); |
|
1489 |
|
1490 //A valid transaction object is required here in order to exercise the API |
|
1491 TInt busIdI2c = (TInt)(parms[1]); |
|
1492 TConfigI2cBufV01* i2cBuf=NULL; |
|
1493 SET_BUS_TYPE(busIdI2c,EI2c); |
|
1494 SET_CHAN_NUM(busIdI2c,10); |
|
1495 // aDeviceId=1 ... 100kHz ... aTimeoutPeriod=100 ... aTransactionWaitCycles=10 - arbitrary paarmeters. |
|
1496 r=CreateI2cBuf(i2cBuf, EI2cAddr7Bit, 36, ELittleEndian, 100); |
|
1497 if(r!=KErrNone) |
|
1498 { |
|
1499 CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for I2c buffer\n")); |
|
1500 return; // Can't proceed if can't access request parameters |
|
1501 } |
|
1502 |
|
1503 TIicBusTransfer* tfer = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,i2cBuf); |
|
1504 if(tfer == NULL) |
|
1505 { |
|
1506 CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for the transfer\n")); |
|
1507 delete i2cBuf; |
|
1508 return; |
|
1509 } |
|
1510 |
|
1511 TIicBusTransaction* transac = new TIicBusTransaction((TDes8*)i2cBuf, tfer); |
|
1512 if(transac == NULL) |
|
1513 { |
|
1514 CLIENT_PRINT(("DChannelIicClient::DoCancel ERROR - Can't allocate memory for the transaction\n")); |
|
1515 delete i2cBuf; |
|
1516 delete tfer; |
|
1517 return; |
|
1518 } |
|
1519 |
|
1520 r = CancelTransaction(busIdI2c, transac); |
|
1521 Kern::RequestComplete(iClient, status, r); |
|
1522 delete i2cBuf; |
|
1523 delete tfer; |
|
1524 delete transac; |
|
1525 } |
|
1526 #endif/*IIC_STUBS*/ |
1410 |
1527 |
1411 // Function to support preamble testing |
1528 // Function to support preamble testing |
1412 void PreambleCallbackFunc(TIicBusTransaction* /*aTrans*/, TAny* aParam) |
1529 void PreambleCallbackFunc(TIicBusTransaction* /*aTrans*/, TAny* aParam) |
1413 { |
1530 { |
1414 CLIENT_PRINT(("IIC Client: PreambleCallbackFunc invoked\n")); |
1531 CLIENT_PRINT(("IIC Client: PreambleCallbackFunc invoked\n")); |
2395 { |
2510 { |
2396 TTestIicChannelInterface channelInterface(DIicBusChannel::EMaster, DIicBusChannel::EI2c, DIicBusChannel::EHalfDuplex); |
2511 TTestIicChannelInterface channelInterface(DIicBusChannel::EMaster, DIicBusChannel::EI2c, DIicBusChannel::EHalfDuplex); |
2397 r = channelInterface.TestInterface(); |
2512 r = channelInterface.TestInterface(); |
2398 break; |
2513 break; |
2399 } |
2514 } |
|
2515 case(RBusDevIicClient::ETestSpare1): |
|
2516 { |
|
2517 r = Spare1((TInt)a1); |
|
2518 break; |
|
2519 } |
|
2520 case(RBusDevIicClient::ETestStaticEx): |
|
2521 { |
|
2522 r = StaticExtension((TUint32)a1, (TUint)RBusDevIicClient::ECtlIoNone, NULL, NULL); |
|
2523 break; |
|
2524 } |
2400 #endif |
2525 #endif |
2401 |
|
2402 default: |
2526 default: |
2403 { |
2527 { |
2404 CLIENT_PRINT(("DChannelIicClient::DoControl - unrecognised value for aId=0x%x\n",aId)); |
2528 CLIENT_PRINT(("DChannelIicClient::DoControl - unrecognised value for aId=0x%x\n",aId)); |
2405 r=KErrArgument; |
2529 r=KErrArgument; |
2406 break; |
2530 break; |