First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32/drivers/camerasc/cameraldd.cpp
18 #include <drivers/camerasc.h>
19 #include <kernel/kern_priv.h>
20 #include <kernel/cache.h>
22 //#define __KTRACE_CAM(s) s;
23 #define __KTRACE_CAM(s)
25 #define DISCARD_COMPLETED_TO_AVOID_OVERFLOW
27 static const char KCameraLddPanic[]="CameraSc LDD";
30 Standard export function for LDDs. This creates a DLogicalDevice derived object,
31 in this case, DSoundScLddFactory.
33 DECLARE_STANDARD_LDD()
35 return new DCameraScLddFactory;
39 Constructor for the camera driver factory class.
41 DCameraScLddFactory::DCameraScLddFactory()
45 __KTRACE_CAM(Kern::Printf(">DCameraScLddFactory::DCameraScLddFactory"));
47 // Set version number for this device.
48 iVersion=RDevCameraSc::VersionRequired();
50 // Indicate that units / PDD are supported.
51 iParseMask=KDeviceAllowUnit|KDeviceAllowPhysicalDevice;
53 // Leave the units decision to the PDD
54 iUnitsMask=0xffffffff;
58 Second stage constructor for the camera driver factory class.
59 This must at least set a name for the driver object.
60 @return KErrNone if successful, otherwise one of the other system wide error codes.
62 TInt DCameraScLddFactory::Install()
64 return(SetName(&KDevCameraScName));
68 Return the 'capabilities' of the camera driver in general.
69 Called in the response to an RDevice::GetCaps() request.
70 @param aDes A user-side descriptor to write the capabilities information into.
72 void DCameraScLddFactory::GetCaps(TDes8 &aDes) const
74 // Create a capabilities object
75 TCapsDevCameraV01 caps;
76 caps.iVersion=iVersion;
78 // Write it back to user memory
79 Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
83 Called by the kernel's device driver framework to create a logical channel.
84 This is called in the context of the client thread which requested the creation of a logical
85 channel - through a call to RBusLogicalChannel::DoCreate().
86 The thread is in a critical section.
87 @param aChannel Set by this function to point to the created logical channel.
88 @return KErrNone if successful, otherwise one of the other system wide error codes.
90 TInt DCameraScLddFactory::Create(DLogicalChannelBase*& aChannel)
92 __KTRACE_CAM(Kern::Printf(">DCameraScLddFactory::Create"));
94 aChannel=new DCameraScLdd;
102 Check whether a channel has is currently open on the specified unit.
103 @param aUnit The number of the unit to be checked.
104 @return ETrue if a channel is open on the specified channel, EFalse otherwise.
105 @pre The unit info. mutex must be held.
107 TBool DCameraScLddFactory::IsUnitOpen(TInt aUnit)
109 return(iUnitsOpenMask&(1<<aUnit));
113 Attempt to change the state of the channel open status for a particular channel.
114 @param aUnit The number of the unit to be updated.
115 @param aIsOpenSetting The required new state for the channel open status: either ETrue to set the status to open or
116 EFalse to set the status to closed.
117 @return KErrNone if the status was updated successfully;
118 KErrInUse if an attempt has been made to set the channnel status to open while it is already open.
120 TInt DCameraScLddFactory::SetUnitOpen(TInt aUnit,TBool aIsOpenSetting)
122 NKern::FMWait(&iUnitInfoMutex); // Acquire the unit info. mutex.
124 // Fail a request to open an channel that is already open
125 if (aIsOpenSetting && IsUnitOpen(aUnit))
127 NKern::FMSignal(&iUnitInfoMutex); // Release the unit info. mutex.
131 // Update the open status as requested
133 iUnitsOpenMask|=(1<<aUnit);
135 iUnitsOpenMask&=~(1<<aUnit);
137 NKern::FMSignal(&iUnitInfoMutex); // Release the unit info. mutex.
142 Constructor for the camera driver logical channel.
144 DCameraScLdd::DCameraScLdd()
145 : iRequestQueue(&iMutex),
146 iRestartDfc(DCameraScLdd::RestartDfc,this,5),
147 iPowerDownDfc(DCameraScLdd::PowerDownDfc,this,3),
148 iPowerUpDfc(DCameraScLdd::PowerUpDfc,this,3)
151 // iCaptureMode=ECaptureModeImage;
155 // iPowerHandler=NULL;
156 // iImageGatherCount=0;
158 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DCameraScLdd"));
160 iUnit=-1; // Invalid unit number
162 // Get pointer to client thread's DThread object
163 iOwningThread=&Kern::CurrentThread();
165 // Open a reference on client thread so it's control block can't dissapear until
166 // this driver has finished with it. Note, this call to Open() can't fail since
167 // it is the thread we are currently running in
168 iOwningThread->Open();
172 Destructor for the camera driver logical channel.
173 This is called in the context of the client thread once a 'ECloseMsg' message has been
174 sent to the device driver DFC thread.
176 DCameraScLdd::~DCameraScLdd()
178 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::~DCameraScLdd"));
182 // Remove and delete the power handler.
185 iPowerHandler->Remove();
186 delete iPowerHandler;
189 if (iCaptureModeConfig)
191 // Delete any buffers and shared chunk we created.
192 for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++)
194 if (iCaptureModeConfig[captureMode].iBufManager)
195 delete iCaptureModeConfig[captureMode].iBufManager;
198 // Delete the buffer config. info. structure.
199 for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++)
201 if (iCaptureModeConfig[captureMode].iBufConfig)
202 Kern::Free(iCaptureModeConfig[captureMode].iBufConfig);
205 if (iCaptureModeConfig)
206 delete[] iCaptureModeConfig;
208 // Close our reference on the client thread
209 Kern::SafeClose((DObject*&)iOwningThread,NULL);
211 // Clear the 'units open mask' in the LDD factory.
213 ((DCameraScLddFactory*)iDevice)->SetUnitOpen(iUnit,EFalse);
217 Second stage constructor for the camera driver - called by the kernel's device driver framework.
218 This is called in the context of the client thread which requested the creation of a logical channel
219 (e.g. through a call to RBusLogicalChannel::DoCreate()).
220 The thread is in a critical section.
221 @param aUnit The unit argument supplied by the client. This is checked by the PDD and not used here.
222 @param aInfo The info argument supplied by the client. Always NULL in this case.
223 @param aVer The version argument supplied by the client.
224 @return KErrNone if successful, otherwise one of the other system wide error codes.
226 TInt DCameraScLdd::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
228 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoCreate"));
230 // Check the client has EMultimediaDD capability.
231 if (!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by ECAMERA.LDD (Camera driver)")))
232 return(KErrPermissionDenied);
234 // Check that the camera driver version specified by the client is compatible.
235 if (!Kern::QueryVersionSupported(RDevCameraSc::VersionRequired(),aVer))
236 return(KErrNotSupported);
238 // Check that a channel hasn't already been opened on this unit.
239 TInt r=((DCameraScLddFactory*)iDevice)->SetUnitOpen(aUnit,ETrue); // Try to update 'units open mask' in the LDD factory.
244 // Create the power handler
245 iPowerHandler=new DCameraScPowerHandler(this);
247 return(KErrNoMemory);
248 iPowerHandler->Add();
250 // Create the pending capture request list
251 r=iRequestQueue.Create(iOwningThread);
255 // Initialise the PDD
256 ((DCameraScPdd*)iPdd)->iLdd=this;
258 // Setup the default camera config
259 iCaptureMode=ECamCaptureModeImage;
261 iCaptureModeConfig = new TCaptureModeConfig[ECamCaptureModeMax];
262 if(!iCaptureModeConfig)
264 TInt capsSize = Pdd()->CapsSize();
267 capsBuf = Kern::Alloc(capsSize);
271 // Query the driver for its capabilities and set a default pixel format
272 // and frame size for each available capture mode.
273 TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize );
274 Pdd()->Caps(capsPtr);
276 TCameraCapsV02* caps = (TCameraCapsV02*) capsPtr.Ptr();
277 SDevCamPixelFormat* pixelFormat = (SDevCamPixelFormat*) (caps + 1);
278 SDevCamFrameSize* frameSize;
279 TAny* frameSizeCapsBuf=0;
280 TPtr8 frameSizeCapsPtr(0,0,0);
282 // Set the cache to hold the default dynamic attribute values.
283 iBrightnessValue = caps->iDynamicRange[ECamAttributeBrightness].iDefault;
284 iContrastValue = caps->iDynamicRange[ECamAttributeContrast].iDefault;
285 iColorEffectValue = caps->iDynamicRange[ECamAttributeColorEffect].iDefault;
287 for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++)
289 if ((captureMode==ECamCaptureModeImage) && (caps->iNumImagePixelFormats==0))
292 if ((captureMode==ECamCaptureModeVideo) && (caps->iNumVideoPixelFormats==0))
295 if ((captureMode==ECamCaptureModeViewFinder) && (caps->iNumViewFinderPixelFormats==0))
298 iCaptureModeConfig[captureMode].iCamConfig.iPixelFormat=*pixelFormat;
299 frameSizeCapsBuf = Kern::Alloc(pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize));
300 new (&frameSizeCapsPtr) TPtr8((TUint8*)frameSizeCapsBuf, pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize), pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize));
301 r=Pdd()->FrameSizeCaps((TDevCamCaptureMode)captureMode, pixelFormat->iPixelFormat, frameSizeCapsPtr);
304 Kern::Free(frameSizeCapsBuf);
307 frameSize=(SDevCamFrameSize*) frameSizeCapsPtr.Ptr();
308 iCaptureModeConfig[captureMode].iCamConfig.iFrameSize = *frameSize;
309 iCaptureModeConfig[captureMode].iCamConfig.iFrameRate = frameSize->iMinFrameRate;
310 Kern::Free(frameSizeCapsBuf);
312 iCaptureModeConfig[captureMode].iCamConfig.iFlashMode = ECamFlashNone;
313 iCaptureModeConfig[captureMode].iCamConfig.iExposureMode = ECamExposureAuto;
314 iCaptureModeConfig[captureMode].iCamConfig.iWhiteBalanceMode = ECamWBAuto;
315 iCaptureModeConfig[captureMode].iCamConfig.iZoom = 0;
316 iCaptureModeConfig[captureMode].iCamConfig.iPixelWidthInBytes = 0;
319 // Setup the default buffer config.
320 r=ReAllocBufferConfigInfo(0); // Zeros the structure
323 for (captureMode=0; captureMode < ECamCaptureModeMax; captureMode++)
325 iCaptureModeConfig[captureMode].iBufConfig->iNumBuffers=KDefaultNumClientBuffers;
328 // Set up the correct DFC queue and enable the reception of client messages.
329 TDfcQue* dfcq=((DCameraScPdd*)iPdd)->DfcQ(aUnit);
331 iRestartDfc.SetDfcQ(dfcq);
332 iPowerDownDfc.SetDfcQ(dfcq);
333 iPowerUpDfc.SetDfcQ(dfcq);
336 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::DoCreate"));
342 Shutdown the camera device.
343 Terminate all device activity and power down the hardware.
345 void DCameraScLdd::Shutdown()
347 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::Shutdown"));
351 // Power down the hardware
354 // Cancel any requests that we may be handling
355 DoCancel(RDevCameraSc::EAllRequests);
357 // Make sure DFCs are not queued.
358 iRestartDfc.Cancel();
359 iPowerDownDfc.Cancel();
360 iPowerUpDfc.Cancel();
364 Notification to the driver that a handle to it has been requested by a user thread.
365 The use of a camera driver channel is restricted here to a single thread (that has
366 EMultimediaDD capability).
367 @param aThread A pointer to thread which is requesting the handle.
368 @param aType Whether the requested handle is thread or process relative.
369 @return KErrNone, if the request is for a thread relative handle - originating from
370 the same the thread that created the channel object;
371 KErrAccessDenied, otherwise.
373 TInt DCameraScLdd::RequestUserHandle(DThread* aThread, TOwnerType aType)
375 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::RequestUserHandle"));
377 // Ensure that each channel can only be used by a single thread.
378 if (aType!=EOwnerThread || aThread!=iOwningThread)
379 return(KErrAccessDenied);
384 Process a request on this logical channel
385 Called in the context of the client thread.
386 @param aReqNo The request number:
387 ==KMaxTInt: a 'DoCancel' message;
388 >=0: a 'DoControl' message with function number equal to value.
389 <0: a 'DoRequest' message with function number equal to ~value.
390 @param a1 The first request argument. For DoRequest(), this is a pointer to the TRequestStatus.
391 @param a2 The second request argument. For DoRequest(), this is a pointer to the 2 actual TAny* arguments.
392 @return The result of the request. This is ignored by device driver framework for DoRequest().
394 TInt DCameraScLdd::Request(TInt aReqNo, TAny* a1, TAny* a2)
396 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::Request(%d)",aReqNo));
398 if (aReqNo<RDevCameraSc::EMsgControlMax && aReqNo>(~RDevCameraSc::EMsgRequestMax))
400 // Implement in the context of the kernel thread - prepare and issue a kernel message.
401 r=DLogicalChannel::Request(aReqNo,a1,a2);
405 // Implement in the context of the client thread.
406 // Decode the message type and dispatch it to the relevent handler function.
407 if ((TUint)aReqNo<(TUint)KMaxTInt)
408 r=DoControl(aReqNo,a1,a2); // DoControl - process the request.
410 else if (aReqNo==KMaxTInt)
412 r=DoCancel((TInt)a1); // DoCancel - cancel the request.
420 // NotifyNewImage() during image capture mode is another case which must be handled in the kernel thread.
421 if (iCaptureMode==ECamCaptureModeImage && func==RDevCameraSc::ERequestNotifyNewImage)
422 r=DLogicalChannel::Request(aReqNo,a1,a2);
425 // Read the arguments from the client thread and process the request.
427 kumemget32(a,a2,sizeof(a));
428 TRequestStatus* status=(TRequestStatus*)a1;
429 r=DoRequest(func,status,a[0],a[1]);
431 // Complete request if there was an error
433 Kern::RequestComplete(iOwningThread,status,r);
438 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::Request - %d",r));
443 Process a message for this logical channel.
444 This function is called in the context of the DFC thread.
445 @param aMsg The message to process.
446 The iValue member of this distinguishes the message type:
447 iValue==ECloseMsg, channel close message.
448 iValue==KMaxTInt, a 'DoCancel' message.
449 iValue>=0, a 'DoControl' message with function number equal to iValue.
450 iValue<0, a 'DoRequest' message with function number equal to ~iValue.
452 void DCameraScLdd::HandleMsg(TMessageBase* aMsg)
454 TThreadMessage& m=*(TThreadMessage*)aMsg;
456 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::HandleMsg(%d)",id));
458 // Decode the message type and dispatch it to the relevent handler function.
459 if (id==(TInt)ECloseMsg)
463 m.Complete(KErrNone,EFalse);
466 else if (id<0) // The only DoRequest handled in the kernel thread is NotifyNewImage(ECamCaptureModeImage).
469 TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
470 TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
472 Kern::RequestComplete(iOwningThread,pS,r);
473 m.Complete(KErrNone,ETrue);
477 // Must be DoControl (Cancel is handled in the client thread).
478 TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
484 Process a synchronous 'DoControl' request.
485 This function is called in the context of the DFC thread.
486 @param aFunction The request number.
487 @param a1 The first request argument.
488 @param a2 The second request argument.
489 @return KErrNone if successful, otherwise one of the other system wide error codes.
491 TInt DCameraScLdd::DoControl(TInt aFunction, TAny* a1, TAny* a2)
493 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoControl(%d)",aFunction));
495 TInt r=KErrNotSupported;
498 case RDevCameraSc::EControlCaps:
500 r = GetSensorCaps(a1);
503 case RDevCameraSc::EControlSetCaptureMode:
505 // Change the capture mode.
506 r=SetCaptureMode((TInt)a1);
509 case RDevCameraSc::EControlSetCamConfig:
511 // Set the new camera configuration.
512 NKern::ThreadEnterCS();
513 r=SetCamConfig((TInt)a1, (const TDesC8*)a2);
514 NKern::ThreadLeaveCS();
517 case RDevCameraSc::EControlGetCamConfig:
519 // Write the config to the client.
520 TPtrC8 ptr((const TUint8*)&iCaptureModeConfig[(TInt)a1].iCamConfig,sizeof(iCaptureModeConfig[(TInt)a1].iCamConfig));
521 Kern::InfoCopy(*((TDes8*)a2),ptr);
525 case RDevCameraSc::EControlGetBufferConfig:
526 if (iCaptureModeConfig[(TInt)a1].iBufConfig)
528 // Write the buffer config to the client.
529 TPtrC8 ptr((const TUint8*)&(*iCaptureModeConfig[(TInt)a1].iBufConfig),iCaptureModeConfig[(TInt)a1].iBufConfigSize);
530 Kern::InfoCopy(*((TDes8*)a2),ptr);
534 case RDevCameraSc::EControlSetBufConfigChunkCreate:
535 // Need to be in critical section while deleting an exisiting config and creating a new one
536 NKern::ThreadEnterCS();
537 r=SetBufConfig((TInt)a1,(TInt)a2);
538 NKern::ThreadLeaveCS();
540 case RDevCameraSc::EControlSetBufConfigChunkOpen:
541 SSetBufConfigChunkOpenInfo info;
542 r=Kern::ThreadRawRead(iOwningThread,a2,&info,sizeof(info));
545 // Need to be in critical section while deleting an exisiting config and creating a new one
546 NKern::ThreadEnterCS();
547 r=SetBufConfig((TInt)a1,info.iBufferConfigBuf,info.iChunkHandle);
548 NKern::ThreadLeaveCS();
551 case RDevCameraSc::EControlChunkClose:
552 r=ChunkClose((TInt)a1);
554 case RDevCameraSc::EControlStart:
557 case RDevCameraSc::EControlStop:
558 if (iState==ECapturing)
561 DoCancel(1<<RDevCameraSc::ERequestNotifyNewImage);
570 case RDevCameraSc::EControlReleaseBuffer:
571 r=ReleaseBuffer((TInt)a1);
573 case RDevCameraSc::EControlNotifyNewImageSpecificCancel:
575 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
576 iRequestQueue.Cancel((TRequestStatus*)a1);
577 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
582 case RDevCameraSc::EControlBufferIdToOffset:
584 // a1 has pointer to buffer for search criteria
585 // a2 has pointer to offset for result
586 TDevCamBufferModeAndId info;
587 TPtr8 inDesc((TUint8*)(&info), sizeof(info));
589 r = Kern::ThreadDesRead(iOwningThread,a1,inDesc,0);
593 TDevCamCaptureMode captureMode = info.iCaptureMode;
596 DBufferManager* mgr = iCaptureModeConfig[captureMode].iBufManager;
599 if (mgr->iImageBuffer[id].iId == id)
601 kumemput32(a2, &mgr->iImageBuffer[id].iChunkOffset, sizeof(TInt));
609 case RDevCameraSc::EControlCapsSize:
611 r = Pdd()->CapsSize();
614 case RDevCameraSc::EControlFrameSizeCaps:
616 r = GetFrameSizeCaps(a1, a2);
620 case RDevCameraSc::EControlSetDynamicAttribute:
622 NKern::ThreadEnterCS();
623 r = SetDynamicAttribute((TInt)a1, (TUint)a2);
624 NKern::ThreadLeaveCS();
628 case RDevCameraSc::EControlGetDynamicAttribute:
630 TInt attribute = (TInt)(a1);
633 r = GetDynamicAttribute(attribute, value);
636 kumemput32(a2, &value, sizeof(TUint));
647 Process an asynchronous 'DoRequest' request.
648 This function is called in the context of the DFC thread.
649 @param aFunction The request number.
650 @param aStatus A pointer to the TRequestStatus.
651 @param a1 The first request argument.
652 @param a2 The second request argument.
653 @return KErrNone if successful, otherwise one of the other system wide error codes.
655 TInt DCameraScLdd::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* /*a1*/, TAny* /*a2*/)
657 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoRequest(%d)",aFunction));
659 TInt r=KErrNotSupported;
662 case RDevCameraSc::ERequestNotifyNewImage:
663 r=NotifyNewImage(aStatus);
667 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::DoRequest - %d",r));
672 Process the cancelling of asynchronous requests.
673 This function is called in the context of the DFC thread.
674 @param aMask A mask indicating which requests need to be cancelled.
675 @return The result of the cancel. Either KErrNone if successful, otherwise one of the other
676 system wide error codes.
678 TInt DCameraScLdd::DoCancel(TUint aMask)
680 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoCancel(%08x)",aMask));
682 if (aMask&(1<<RDevCameraSc::ERequestNotifyNewImage))
684 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
685 iRequestQueue.CancelAll();
686 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
692 @pre The thread must be in a critical section.
694 TInt DCameraScLdd::ReAllocBufferConfigInfo(TInt aNumBuffers)
696 for (TInt captureMode=0; captureMode < ECamCaptureModeMax; captureMode++)
698 if (iCaptureModeConfig[captureMode].iBufConfig)
700 Kern::Free(iCaptureModeConfig[captureMode].iBufConfig);
701 iCaptureModeConfig[captureMode].iBufConfig=NULL;
704 iCaptureModeConfig[captureMode].iBufConfigSize=aNumBuffers*(sizeof(SBufSpecList)); // Size of the three integers that hold the offset to the start of each buffer and the buffer id.
705 iCaptureModeConfig[captureMode].iBufConfigSize+=sizeof(TSharedChunkBufConfigBase);
706 iCaptureModeConfig[captureMode].iBufConfig=(TCameraSharedChunkBufConfig*)Kern::AllocZ(iCaptureModeConfig[captureMode].iBufConfigSize);
707 if (!iCaptureModeConfig[captureMode].iBufConfig)
708 return(KErrNoMemory);
714 Reallocate memory for the new buffer configuration.
715 @param aNumBuffers The number of buffers.
716 @pre The thread must be in a critical section.
718 TInt DCameraScLdd::ReAllocBufferConfigInfo(TInt aCaptureMode, TInt aNumBuffers)
720 if (iCaptureModeConfig[aCaptureMode].iBufConfig)
722 Kern::Free(iCaptureModeConfig[aCaptureMode].iBufConfig);
723 iCaptureModeConfig[aCaptureMode].iBufConfig=NULL;
726 iCaptureModeConfig[aCaptureMode].iBufConfigSize=aNumBuffers*(sizeof(SBufSpecList)); // Size of the three integers that hold the offset to the start of each buffer and the buffer id.
727 iCaptureModeConfig[aCaptureMode].iBufConfigSize+=sizeof(TSharedChunkBufConfigBase);
728 iCaptureModeConfig[aCaptureMode].iBufConfig=(TCameraSharedChunkBufConfig*)Kern::AllocZ(iCaptureModeConfig[aCaptureMode].iBufConfigSize);
729 if (!iCaptureModeConfig[aCaptureMode].iBufConfig)
730 return(KErrNoMemory);
736 @return A handle to the shared chunk for the owning thread (a value >0), if successful;
737 otherwise one of the other system wide error codes, (a value <0).
738 @param aCamConfigBuf The supplied camera configuration.
739 @pre The thread must be in a critical section.
741 TInt DCameraScLdd::SetCamConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf)
743 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetCamConfig()"));
745 // Set the configuration of the sensor
746 TInt r=DoSetConfig(aCaptureMode, aCamConfigBuf);
751 Allows changing of the dynamic settings.
752 Checks locally the validity of the arguments passed so as to increase performance by not
753 forcing a context switch.
755 If the setting has been accepted by the sensor the new value is cached by the LDD so further
756 querying does not involve another context switch.
758 @param aAttribute An enum identifying the dynamic attribute to change.
759 @param aValue The attributes value.
760 @return KErrNone if successful, KErrNotSupported if not supported, KErrArgument if aValue out of range.
761 Otherwise, one of the system wide error codes.
762 @pre The thread must be in a critical section.
764 TInt DCameraScLdd::SetDynamicAttribute(TInt aAttribute, TUint aValue)
766 TUint* attrCachePtr = NULL;
767 TInt err = KErrNotSupported;
771 case ECamAttributeBrightness:
772 err = Pdd()->SetBrightness(aValue);
773 attrCachePtr = &iBrightnessValue;
776 case ECamAttributeContrast:
777 err = Pdd()->SetContrast(aValue);
778 attrCachePtr = &iContrastValue;
781 case ECamAttributeColorEffect:
782 err = Pdd()->SetColorEffect(aValue);
783 attrCachePtr = &iColorEffectValue;
792 // Cache the set value.
793 __ASSERT_DEBUG(attrCachePtr, Kern::Fault(KCameraLddPanic, __LINE__));
794 *attrCachePtr = aValue;
802 Allows querying of a dynamic setting.
803 The value is read from the cached LDD values.
805 @param aAttribute An enum identifying the dynamic attribute to change.
806 @param aValue A reference to a variable that will receive the attribute value.
807 @return KErrNone if successful, KErrNotFound if aAttribute is an unsupported
808 setting. The parameter aValue is not changed if this function fails.
810 TInt DCameraScLdd::GetDynamicAttribute(TInt aAttribute, TUint& aValue)
814 case ECamAttributeBrightness:
815 aValue = iBrightnessValue;
818 case ECamAttributeContrast:
819 aValue = iContrastValue;
822 case ECamAttributeColorEffect:
823 aValue = iColorEffectValue;
835 Updates the buffer configuration of the camera for the specified capture mode.
836 @return A handle to the shared chunk for the owning thread (a value >0), if successful;
837 otherwise one of the other system wide error codes, (a value <0).
839 TInt DCameraScLdd::SetBufConfig(TInt aCaptureMode, TInt aNumBuffers)
841 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetBufConfig(CaptureMode=%d,NumBuffers=%d)",aCaptureMode,aNumBuffers));
843 // Free any memory and chunk already allocated
844 TInt r=ChunkClose(aCaptureMode);
848 // Allocate a new shared chunk and create the specified number of buffers within it.
849 TInt buffersize=((iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth*iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight) * iCaptureModeConfig[aCaptureMode].iCamConfig.iPixelWidthInBytes);
850 __KTRACE_CAM(Kern::Printf(">>DCameraScLdd::SetBufConfig - iFrameSize:%d, iPixelWidthInBytes:%d => bufferSize:%d",(iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth*iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight),iCaptureModeConfig[aCaptureMode].iCamConfig.iPixelWidthInBytes,buffersize));
851 iCaptureModeConfig[aCaptureMode].iBufManager=new DBufferManager(this);
852 if (!iCaptureModeConfig[aCaptureMode].iBufManager)
853 return(KErrNoMemory);
854 r=iCaptureModeConfig[aCaptureMode].iBufManager->Create(aNumBuffers,buffersize);
858 // Update the LDD's chunk/buffer geometry info.
859 r=ReAllocBufferConfigInfo(aCaptureMode, aNumBuffers);
862 iCaptureModeConfig[aCaptureMode].iBufManager->GetBufConfig(*iCaptureModeConfig[aCaptureMode].iBufConfig);
864 // Create handle to the shared chunk for the owning thread.
865 r=Kern::MakeHandleAndOpen(iOwningThread,iCaptureModeConfig[aCaptureMode].iBufManager->iChunk);
868 // And save the the chunk and handle for later. Normally the chunk handle will be closed when the chunk
869 // is closed, but if the chunk is re-allocated then it will need to be closed before re-allocation.
870 iCaptureModeConfig[aCaptureMode].iChunkHandle=r;
873 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::SetBufConfig - %d",r));
878 Updates the buffer configuration of the camera, which has been supplied by the user, for the specified capture mode.
879 @param aCaptureMode The capture mode for which the setting of the buffer configuration is made.
880 @param aBufferConfigBuf A buffer that holds the buffer configuration for the camera.
881 @param aChunkHandle A handle for the shared chunk supplied by the client.
882 @return KErrNone if successful, otherwise one of the other system wide error codes.
883 @pre The thread must be in a critical section.
885 TInt DCameraScLdd::SetBufConfig(TInt aCaptureMode,const TDesC8* aBufferConfigBuf,TInt aChunkHandle)
887 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetConfig(Handle-%d)",aChunkHandle));
889 // Read the buffer config structure from the client.
891 TPtr8 ptr((TUint8*)&numBuffers,sizeof(numBuffers));
892 TInt r=Kern::ThreadDesRead(iOwningThread,aBufferConfigBuf,ptr,0);
895 // Calculate the minimum length of the descriptor.
896 TInt minDesLen=(numBuffers*sizeof(SBufSpecList))+sizeof(TSharedChunkBufConfigBase);
897 r=Kern::ThreadGetDesLength(iOwningThread,aBufferConfigBuf);
899 return(KErrArgument);
900 r=ReAllocBufferConfigInfo(aCaptureMode, numBuffers);
903 ptr.Set((TUint8*)iCaptureModeConfig[aCaptureMode].iBufConfig,0,iCaptureModeConfig[aCaptureMode].iBufConfigSize);
904 r=Kern::ThreadDesRead(iOwningThread,aBufferConfigBuf,ptr,0);
908 // Free any memory and chunk already allocated
909 r=ChunkClose(aCaptureMode);
913 // Open the shared chunk supplied and create buffer objects for the committed buffers within it.
914 iCaptureModeConfig[aCaptureMode].iBufManager=new DBufferManager(this);
915 if (!iCaptureModeConfig[aCaptureMode].iBufManager)
916 return(KErrNoMemory);
917 r=iCaptureModeConfig[aCaptureMode].iBufManager->Create(*iCaptureModeConfig[aCaptureMode].iBufConfig,aChunkHandle,iOwningThread);
921 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::SetConfig - %d",KErrNone));
926 Frees the buffer manager associated with a chunk, and closes the chunk itself. The chunk being closed,
927 and its associated DBufferManager instance should have been allocated by the device driver. However,
928 this is not a requirement.
929 @param aCaptureMode The capture mode for which to free the buffer manager and chunk.
930 @return KErrNone if successful.
931 KErrInUse if an attempt has been made to free the memory and chunk while they are in use.
932 Otherwise one of the other system-wide error codes.
934 TInt DCameraScLdd::ChunkClose(TInt aCaptureMode)
936 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::ChunkClose(Capture Mode-%d)",aCaptureMode));
938 if(iCaptureMode == aCaptureMode)
940 if (iState==ECapturing)
944 // Delete any existing buffers
945 if (iCaptureModeConfig[aCaptureMode].iBufManager)
947 delete iCaptureModeConfig[aCaptureMode].iBufManager;
948 iCaptureModeConfig[aCaptureMode].iBufManager=NULL;
951 // If a handle to the shared chunk was created, close it, using the handle of the thread on which
952 // it was created, in case a different thread is now calling us
953 if (iCaptureModeConfig[aCaptureMode].iChunkHandle>0)
955 Kern::CloseHandle(iOwningThread,iCaptureModeConfig[aCaptureMode].iChunkHandle);
956 iCaptureModeConfig[aCaptureMode].iChunkHandle=0;
963 Set the current capture mode and submits the camera configuration to the PDD, passing it as a descriptor
964 to support future changes to the config structure.
966 @param aCaptureMode The capture mode that the camera switches to.
967 @return KErrNone if successful;
968 otherwise one of the other system-wide error codes.
970 TInt DCameraScLdd::SetCaptureMode(TInt aCaptureMode)
972 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::SetCaptureMode(Mode-%d)",aCaptureMode));
975 if(aCaptureMode >= ECamCaptureModeMax || aCaptureMode < 0)
981 if (!iCaptureModeConfig[aCaptureMode].iBufManager)
987 iCaptureMode=(TDevCamCaptureMode)aCaptureMode; // The capture mode has already been checked for its validity.
989 __KTRACE_CAM(Kern::Printf("DCameraScLdd::SetCaptureMode: iFrameSize:%dx%d)",iCaptureModeConfig[iCaptureMode].iCamConfig.iFrameSize.iWidth, iCaptureModeConfig[iCaptureMode].iCamConfig.iFrameSize.iHeight));
991 // Call the PDD to change the hardware configuration according to the new capture mode.
992 // Pass it as a descriptor - to support future changes to the config structure.
993 TPtr8 ptr((TUint8*)&iCaptureModeConfig[iCaptureMode].iCamConfig,sizeof(iCaptureModeConfig[iCaptureMode].iCamConfig),sizeof(iCaptureModeConfig[iCaptureMode].iCamConfig));
994 r=Pdd()->SetConfig(ptr);
1002 Process a start image capture request from the client - in the capture mode supplied.
1003 If this is a free running mode then the PDD is called straight away to commence capturing frames. In one shot mode the driver postpones the capturing
1004 of frames until a NotifyNewImage() request is received.
1005 @return KErrNone if successful; whether capture mode was actually started or deferred until NotifyNewImage();
1006 KErrNotReady if SetConfig() has not been previously called;
1007 otherwise one of the other system-wide error codes.
1009 TInt DCameraScLdd::Start()
1011 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::Start(Current Mode-%d)",iCaptureMode));
1013 if (iState==ECapturing)
1017 // Only continue if the mode being started has been configured
1018 if (iCaptureModeConfig[iCaptureMode].iBufManager)
1023 else if (iState==EConfigured)
1025 iCaptureModeConfig[iCaptureMode].iBufManager->Reset();
1026 if (iCaptureMode!=ECamCaptureModeImage)
1037 Start the PDD capturing images.
1038 @return KErrNone if successful, otherwise one of the other system wide error codes.
1040 TInt DCameraScLdd::DoStart()
1042 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoStart()"));
1044 DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager;
1045 TLinAddr linAddr=(bufManager->iChunkBase)+(bufManager->iCurrentBuffer->iChunkOffset);
1046 TPhysAddr physAddr=bufManager->iCurrentBuffer->iPhysicalAddress;
1047 TInt r=Pdd()->Start(iCaptureMode,linAddr,physAddr);
1050 * James Cooper: Uncommenting this code will cause the ASSERT_DEBUG in SetImageCaptured() to fail
1051 * if (r==KErrNone && bufManager->iNextBuffer)
1053 linAddr=(bufManager->iChunkBase)+(bufManager->iNextBuffer->iChunkOffset);
1054 physAddr=bufManager->iNextBuffer->iPhysicalAddress;
1055 r=Pdd()->CaptureNextImage(linAddr,physAddr);
1062 Process a notify a new image request from the client.
1063 If there is an image already available then the request is completed straight away, otherwise it is added to the capture request queue.
1064 @param aStatus The request status to be signalled when the request is complete. If the request is successful then this is set
1065 to the offset within the shared chunk where the record data resides. Alternatively, if an error occurs,
1066 it will be set to one of the system wide error values.
1067 @return KErrNone if successful - whether the request was completed or simply queued;
1068 KErrNotReady if Start() hasn't been previousely called;
1069 KErrInUse: if the client needs to free up buffers before further requests can be accepted;
1070 KErrGeneral: if the client has more requests queued than there are buffers;
1071 otherwise one of the other system wide error codes.
1073 TInt DCameraScLdd::NotifyNewImage(TRequestStatus* aStatus)
1075 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage(%x) - iState(%d)",aStatus,iState));
1076 DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager;
1078 if (iState!=ECapturing || !bufManager)
1079 return(KErrNotReady);
1081 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
1082 if (iCaptureMode!=ECamCaptureModeImage)
1084 // We're operating in one of the free running modes, see if an image is already available.
1085 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage - Getting image for client"));
1086 TImageBuffer* buf=bufManager->GetImageForClient(EFalse);
1089 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage - There is an image available already"));
1090 // There is an image available already - complete the request.
1092 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1095 // Only complete if successful here. Errors will be completed on returning from this method.
1096 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::NotifyNewImage(iId:%d)",buf->iId));
1097 Kern::RequestComplete(iOwningThread,aStatus,(buf->iId));
1102 // The buffer 'completed' list is empty. If the 'in-use' list contains all the buffers apart from the one being filled
1103 // then let the client know they need to free some buffers.
1104 if (bufManager->iFreeBufferQ.IsEmpty() && !bufManager->iNextBuffer)
1106 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1112 // We're operating in one shot image capture mode. Check if the client needs to free up some buffers
1113 // before we can accept the request.
1114 if (bufManager->iCompletedBufferQ.IsEmpty() && bufManager->iFreeBufferQ.IsEmpty() && !bufManager->iNextBuffer)
1116 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1120 // Enough buffers are available so we can start capturing data. First
1121 // check that there isn't already a capture request in progress.
1122 if (iRequestQueue.IsEmpty())
1124 // No previous request in progress so start the PDD.
1125 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1129 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex again.
1133 // Save the request in the pending queue and return. The request will be completed from the PDD and the DFC thread when
1134 // an image is available.
1135 r=iRequestQueue.Add(aStatus);
1136 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1141 Process a release buffer request from the client.
1142 @param aChunkOffset The chunk offset corresponding to the buffer to be freed.
1143 @return KErrNone if successful;
1144 KErrNotFound if no 'in use' buffer had the specified chunk offset;
1145 KErrNotReady if the driver hasn't been configured for the current capture mode.
1147 TInt DCameraScLdd::ReleaseBuffer(TInt aBufferId)
1149 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::ReleaseBuffer(%d)",aBufferId));
1150 if(!iCaptureModeConfig[iCaptureMode].iBufManager)
1151 return KErrNotReady;
1152 DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager;
1153 TInt chunkOffset = 0;
1156 /* The driver is left in an ECapturing state after capturing frames. However, it can be left in an
1157 EConfigured state as a result of Stop() being called. Stop() cancels all pending capture requests and
1158 leaves the driver in a state in which it can be restarted without needing reconfiguring. */
1159 if (iState!=EOpen && bufManager)
1161 chunkOffset = bufManager->iImageBuffer[aBufferId].iChunkOffset;
1162 TImageBuffer* buf=NULL;
1163 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
1164 buf=bufManager->FindInUseImage(chunkOffset);
1165 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1168 // The buffer specified by the client has been found in the 'in-use' list.
1169 bufManager->Purge(buf);
1176 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
1177 // Release it from the 'in-use list into the 'free' list.
1178 r=bufManager->ReleaseImage(chunkOffset);
1181 // The buffer needs to be queued straight away - so signal this to the PDD
1182 TLinAddr linAddr=(bufManager->iChunkBase)+(bufManager->iNextBuffer->iChunkOffset);
1183 TPhysAddr physAddr=bufManager->iNextBuffer->iPhysicalAddress;
1184 buf=bufManager->iNextBuffer;
1185 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1186 r=Pdd()->CaptureNextImage(linAddr,physAddr);
1187 if (r==KErrNotReady)
1191 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1196 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::ReleaseBuffer() - r(%d)",r));
1201 Called from the PDD in the DFC thread each time it finishes capturing an image frame.
1202 This will complete a pending capture request and update buffer lists.
1203 @param aCaptureMode The capture mode of the image captured. @see TDevCamCaptureMode.
1204 @param aResult The result of the image capture request being completed.
1205 @param aLinAddr If this function returns KErrNone then on return, this holds the linear address of the start of the next buffer
1206 to use for image capture.
1207 @param aPhysAddr If this function returns KErrNone then on return, this holds the physical address that corresponds to the
1208 linear address: aLinAddr.
1209 @return KErrNone if capturing should continue - with holding information on the next buffer to use for image capture.
1210 KErrNotReady if capturing should continue - but with no further buffer available for image capture just yet.
1211 KErrAbort if image capturing should now be terminated.
1213 TInt DCameraScLdd::ImageCaptureCallback(TDevCamCaptureMode /*aCaptureMode*/,TInt aResult,TLinAddr* aLinAddr,TPhysAddr* aPhysAddr)
1215 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::ImageCaptureCallback"));
1217 DBufferManager* bufManager=iCaptureModeConfig[iCaptureMode].iBufManager;
1218 // Update the buffer list and get the next buffer for capture.
1219 NKern::FMWait(&iMutex); // Acquire the buffer/request list mutex.
1220 TImageBuffer* nextBuffer=bufManager->SetImageCaptured(aResult); // Puts the captured image's buffer in the completed buffer queue.
1222 // Check if there is a capture request pending.
1223 if (!iRequestQueue.IsEmpty())
1225 // A capture request is pending.
1226 TBool removeLast=((iCaptureMode==ECamCaptureModeImage) ? (TBool) ETrue : (TBool) EFalse);
1227 TImageBuffer* buf=bufManager->GetImageForClient(removeLast); // Retrieved the captured image from the buffer in the completed buffer queue.
1230 // Update the request pending list and complete the request.
1231 TRequestStatus* rs=iRequestQueue.Remove();
1232 TInt reason=(buf->iResult==KErrNone) ? buf->iId : buf->iResult;
1233 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1234 buf->SyncMemoryAfterDmaRead();
1235 Kern::RequestComplete(iOwningThread,rs,reason); // Complete the request.
1238 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1241 NKern::FMSignal(&iMutex); // Release the buffer/request list mutex.
1243 // Now work out what instruction to give to the PDD
1245 if (iCaptureMode==ECamCaptureModeImage)
1247 // Image capture mode. If we've just completed a one shot request, see if there is yet another one pending.
1248 if (!iRequestQueue.IsEmpty())
1250 // Another request is pending so let the PDD carry on.
1251 // If an error occured we need to first stop and re-start image capture
1252 if (aResult!=KErrNone)
1254 iRestartDfc.Enque(); // Queue a DFC to re-start the PDD later.
1260 r=KErrAbort; // End of image gather mode so stop the PDD.
1265 // One of the free running modes. If an error occured we need to first stop and re-start image capture
1266 if (aResult!=KErrNone)
1268 iRestartDfc.Enque(); // Queue a DFC to re-start the PDD later.
1273 // If capture should continue, check if there is a further buffer available to use for image capture.
1278 *aLinAddr=(bufManager->iChunkBase)+(nextBuffer->iChunkOffset);
1279 *aPhysAddr=nextBuffer->iPhysicalAddress;
1288 Stores the camera configuration passed in from the user after checking and validating it.
1289 @param aCaptureMode The capture mode for which the setting of the camera configuration is made.
1290 @param aCamConfigBuf A buffer that contains the camera configuration.
1291 @return KErrNone if successful
1292 KErrInUse if the camera is capturing an image
1293 KErrArgument if the camera configuration passed in is invalid
1294 otherwise a system wide error code.
1296 TInt DCameraScLdd::DoSetConfig(TInt aCaptureMode, const TDesC8* aCamConfigBuf)
1298 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoSetConfig(CaptureMode=%d)",aCaptureMode));
1300 if(iCaptureMode == aCaptureMode)
1302 if (iState==ECapturing)
1306 // Read the config structure from the client
1307 TCameraConfigV02 config;
1308 TPtr8 ptr((TUint8*)&config,sizeof(config));
1309 TInt r=Kern::ThreadDesRead(iOwningThread,aCamConfigBuf,ptr,0);
1313 // Check that it is compatible with this camera device
1314 r=ValidateConfig(aCaptureMode, config);
1317 if (r == KErrNotFound)
1322 // We're about to replace any previous configuration - so set the
1323 // status back to un-configured. A new buffer configuration must be calculated as a result of that.
1326 // Save the new configuration.
1327 iCaptureModeConfig[aCaptureMode].iCamConfig=config;
1328 iCaptureModeConfig[aCaptureMode].iFrameHeight=iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iHeight;
1329 iCaptureModeConfig[aCaptureMode].iFrameWidth=iCaptureModeConfig[aCaptureMode].iCamConfig.iFrameSize.iWidth;
1331 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::DoSetConfig - %d",KErrNone));
1336 Validates the configuration that is about to be used with the driver.
1337 @param aCaptureMode The capture mode that the configuration is for.
1338 @param aConfig The buffer that contains the camera configuration, as passed in from the user.
1339 @return KErrNotFound if the configuration is not supported by the camera sensor.
1340 KErrNotSupported if the driver does not support aCaptureMode
1341 KErrNone if successful.
1343 TInt DCameraScLdd::ValidateConfig(TInt aCaptureMode, TCameraConfigV02& aConfig)
1345 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::ValidateConfig"));
1347 TInt capsSize = Pdd()->CapsSize();
1348 NKern::ThreadEnterCS();
1349 TAny* capsBuf = Kern::Alloc(capsSize);
1352 NKern::ThreadLeaveCS();
1353 return KErrNoMemory;
1356 TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize );
1357 Pdd()->Caps(capsPtr);
1358 NKern::ThreadLeaveCS();
1360 TCameraCapsV02* camCaps = (TCameraCapsV02*) capsPtr.Ptr();
1363 if(aCaptureMode==ECamCaptureModeImage && camCaps->iNumImagePixelFormats)
1365 r=DoValidateConfig(camCaps, aCaptureMode, aConfig);
1367 else if(aCaptureMode==ECamCaptureModeVideo && camCaps->iNumVideoPixelFormats)
1369 r=DoValidateConfig(camCaps, aCaptureMode, aConfig);
1371 else if(aCaptureMode==ECamCaptureModeViewFinder && camCaps->iNumViewFinderPixelFormats)
1373 r=DoValidateConfig(camCaps, aCaptureMode, aConfig);
1380 // Calculate the pixel width (in bytes) for the format specified
1381 aConfig.iPixelWidthInBytes=aConfig.iPixelFormat.iPixelWidthInBytes;
1384 NKern::ThreadEnterCS();
1385 Kern::Free(capsBuf);
1386 NKern::ThreadLeaveCS();
1388 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::ValidateConfig - %d",r));
1393 Validates the configuration that is about to be used with the driver by checking it against what the camera sensor supports.
1394 @param aCamCaps The buffer that contains the capabilities of the camera driver.
1395 @param aCaptureMode The capture mode that the configuration is for.
1396 @param aConfig The buffer that contains the camera configuration, as passed in from the user.
1397 @return KErrNotFound if the configuration is not supported by the camera sensor
1398 KErrNone if successful
1399 or one of the system wide error values.
1401 TInt DCameraScLdd::DoValidateConfig(TCameraCapsV02* aCamCaps, TInt& aCaptureMode, TCameraConfigV02& aConfig)
1403 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::DoValidateConfig"));
1404 TAny* frameSizeCapsBuf;
1405 TInt frameSizeCapsSize;
1406 SFrameSizeCapsInfo info;
1407 SDevCamFrameSize* frameSize;
1410 SDevCamPixelFormat* pixelFormat;
1414 pixelFormat = (SDevCamPixelFormat*) (aCamCaps + 1);
1415 if(aCaptureMode==ECamCaptureModeImage)
1418 end=aCamCaps->iNumImagePixelFormats;
1420 else if(aCaptureMode==ECamCaptureModeVideo)
1422 start=aCamCaps->iNumImagePixelFormats;
1423 end=aCamCaps->iNumImagePixelFormats + aCamCaps->iNumVideoPixelFormats;
1424 pixelFormat += aCamCaps->iNumImagePixelFormats;
1426 else if(aCaptureMode==ECamCaptureModeViewFinder)
1428 start=aCamCaps->iNumImagePixelFormats+aCamCaps->iNumVideoPixelFormats;
1429 end=aCamCaps->iNumImagePixelFormats + aCamCaps->iNumVideoPixelFormats + aCamCaps->iNumViewFinderPixelFormats;
1430 pixelFormat += aCamCaps->iNumImagePixelFormats;
1431 pixelFormat += aCamCaps->iNumVideoPixelFormats;
1434 return KErrNotSupported;
1436 for (i=start; i<end; i++)
1438 if(aConfig.iPixelFormat.iPixelFormat==pixelFormat->iPixelFormat)
1440 info.iUidPixelFormat = pixelFormat->iPixelFormat;
1441 info.iCaptureMode = (TDevCamCaptureMode) aCaptureMode;
1442 frameSizeCapsSize = pixelFormat->iNumFrameSizes*sizeof(SDevCamFrameSize);
1443 NKern::ThreadEnterCS();
1444 frameSizeCapsBuf = Kern::Alloc(frameSizeCapsSize);
1445 NKern::ThreadLeaveCS();
1446 if (!frameSizeCapsBuf)
1448 return KErrNoMemory;
1450 TPtr8 frameSizeCapsPtr( (TUint8*)frameSizeCapsBuf, frameSizeCapsSize, frameSizeCapsSize );
1451 if ((r = Pdd()->FrameSizeCaps(info.iCaptureMode, info.iUidPixelFormat, frameSizeCapsPtr)) == KErrNone)
1453 frameSize = (SDevCamFrameSize*) frameSizeCapsPtr.Ptr();
1454 for(l=0; l<pixelFormat->iNumFrameSizes; l++ )
1456 if (aConfig.iFrameSize.iWidth == frameSize->iWidth &&
1457 aConfig.iFrameSize.iHeight == frameSize->iHeight &&
1458 aConfig.iFrameRate >= frameSize->iMinFrameRate &&
1459 aConfig.iFrameRate <= frameSize->iMaxFrameRate)
1461 NKern::ThreadEnterCS();
1462 Kern::Free(frameSizeCapsBuf);
1463 NKern::ThreadLeaveCS();
1464 __KTRACE_CAM(Kern::Printf("<DCameraScLdd::DoValidateConfig"));
1469 NKern::ThreadEnterCS();
1470 Kern::Free(frameSizeCapsBuf);
1471 NKern::ThreadLeaveCS();
1472 return KErrNotFound;
1476 NKern::ThreadEnterCS();
1477 Kern::Free(frameSizeCapsBuf);
1478 NKern::ThreadLeaveCS();
1484 return KErrNotFound;
1488 The DFC used to re-start the PDD following a data capture error.
1489 @param aChannel A pointer to the camera driver logical channel object.
1491 void DCameraScLdd::RestartDfc(TAny* aChannel)
1493 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::RestartDfc"));
1495 DCameraScLdd& drv=*(DCameraScLdd*)aChannel;
1497 if (!drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer)
1498 drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer=drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->NextAvailableForCapture();
1499 __ASSERT_ALWAYS(drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iCurrentBuffer,Kern::Fault(KCameraLddPanic,__LINE__));
1501 if (!drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iNextBuffer)
1502 drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->iNextBuffer=drv.iCaptureModeConfig[drv.iCaptureMode].iBufManager->NextAvailableForCapture();
1508 The DFC used to handle power down requests from the power manager before a transition into system
1510 @param aChannel A pointer to the camera driver logical channel object.
1512 void DCameraScLdd::PowerDownDfc(TAny* aChannel)
1514 DCameraScLdd& drv=*(DCameraScLdd*)aChannel;
1516 drv.iPowerHandler->PowerDownDone();
1520 The DFC used to handle power up requests from the power manager following a transition out of system standby.
1521 @param aChannel A pointer to the camera driver logical channel object.
1523 void DCameraScLdd::PowerUpDfc(TAny* aChannel)
1525 DCameraScLdd& drv=*(DCameraScLdd*)aChannel;
1526 drv.iPowerHandler->PowerUpDone();
1529 void DCameraScLdd::PanicClientThread(TInt aReason)
1531 Kern::ThreadKill(iOwningThread, EExitPanic, aReason, KDevCameraScName);
1535 Retrieves the capabilities of the camera sensor.
1536 @param aBuffer A pointer to a descriptor passed in by the user.
1538 TInt DCameraScLdd::GetSensorCaps(TAny* aBuffer)
1540 // Return the capabilities for this device. Read this from the PDD and
1541 // then write it to the client
1542 TInt capsSize = Pdd()->CapsSize();
1545 Kern::KUDesInfo(*((TDes8*)aBuffer), bufferSize, maxBufferSize);
1546 if(capsSize>maxBufferSize)
1548 return KErrArgument;
1550 NKern::ThreadEnterCS();
1551 TAny* capsBuf = Kern::Alloc(capsSize);
1554 NKern::ThreadLeaveCS();
1555 return KErrNoMemory;
1558 TPtr8 capsPtr( (TUint8*)capsBuf, capsSize, capsSize );
1559 Pdd()->Caps(capsPtr);
1560 NKern::ThreadLeaveCS();
1561 Kern::InfoCopy(*((TDes8*)aBuffer), capsPtr.Ptr(), capsSize);
1562 NKern::ThreadEnterCS();
1563 Kern::Free((TAny*)capsBuf);
1564 NKern::ThreadLeaveCS();
1569 Retrieves the frame sizes supported for a given pixel format.
1570 @param aBuffer A pointer to descriptor passed in by the user.
1571 @param aFrameSizeCapsInfo A structure that holds information regarding the requested capabilities.
1573 TInt DCameraScLdd::GetFrameSizeCaps(TAny* aBuffer, TAny* aFrameSizeCapsInfo)
1575 __KTRACE_CAM(Kern::Printf(">DCameraScLdd::GetFrameSizeCaps()"));
1576 TInt frameSizeCapsMaxSize;
1577 TInt frameSizeCapsSize;
1578 Kern::KUDesInfo(*((TDes8*)aBuffer),frameSizeCapsSize,frameSizeCapsMaxSize);
1579 SFrameSizeCapsInfo info;
1580 kumemget((TAny*)&info,aFrameSizeCapsInfo,sizeof(info));
1581 NKern::ThreadEnterCS();
1582 // Allocate memory on the heap for the frame size structure.
1583 TAny* frameSizeCapsBuf = Kern::Alloc(frameSizeCapsMaxSize);
1584 if (!frameSizeCapsBuf)
1586 NKern::ThreadLeaveCS();
1587 return KErrNoMemory;
1589 TPtr8 frameSizeCapsPtr( (TUint8*)frameSizeCapsBuf, frameSizeCapsMaxSize, frameSizeCapsMaxSize );
1590 // Request the frame sizes from the Pdd.
1591 TInt r=Pdd()->FrameSizeCaps(info.iCaptureMode, info.iUidPixelFormat, frameSizeCapsPtr);
1592 NKern::ThreadLeaveCS();
1595 NKern::ThreadEnterCS();
1596 Kern::Free((TAny*)frameSizeCapsBuf);
1597 NKern::ThreadLeaveCS();
1600 Kern::InfoCopy(*((TDes8*)aBuffer),frameSizeCapsPtr.Ptr(), frameSizeCapsMaxSize);
1601 NKern::ThreadEnterCS();
1602 Kern::Free((TAny*)frameSizeCapsBuf);
1603 NKern::ThreadLeaveCS();
1609 Constructor for the buffer manager.
1611 DBufferManager::DBufferManager(DCameraScLdd* aLdd)
1616 // iImageBuffer=NULL;
1620 Destructor for the buffer manager.
1621 @pre The thread must be in a critical section.
1623 DBufferManager::~DBufferManager()
1626 Kern::ChunkClose(iChunk);
1627 delete[] iImageBuffer;
1631 Second stage constructor for the buffer manager. This version creates a shared chunk and a buffer object for each
1632 buffer specified within this. Then it commits memory within the chunk for each of these buffers. This also involves the
1633 creation of a set of buffer lists to manage the buffers.
1634 @param aNumBuffers The number of buffers required in the shared chunk.
1635 @param aBufferSize The size of each buffer required in the shared chunk.
1636 @return KErrNone if successful, otherwise one of the other system wide error codes.
1637 @pre The thread must be in a critical section.
1639 TInt DBufferManager::Create(TInt aNumBuffers,TInt aBufferSize)
1641 __KTRACE_CAM(Kern::Printf(">DBufferManager::Create(Bufs-%d,Sz-%d)",aNumBuffers,aBufferSize));
1643 TInt r=CreateBufferLists(aNumBuffers);
1647 // Calculate the size of the chunk required for the buffer configuration specified.
1648 aBufferSize=Kern::RoundToPageSize(aBufferSize);
1649 TInt pageSize=Kern::RoundToPageSize(1);
1650 // Leave space for guard pages around each buffer. There is a guard page in between each buffer but
1651 // NO guard page before the first buffer or after the last buffer
1652 TUint64 chunkSize=TUint64(aBufferSize+pageSize)*aNumBuffers-pageSize;
1653 if (chunkSize>(TUint64)KMaxTInt)
1654 return(KErrNoMemory); // Need more than 2GB of memory!
1656 // Create the shared chunk. The PDD supplies most of the chunk create info - but not the maximum size.
1657 TChunkCreateInfo info;
1658 info.iMaxSize=(TInt)chunkSize;
1659 iLdd->Pdd()->GetChunkCreateInfo(info); // Call down to the PDD for the rest.
1661 r = Kern::ChunkCreate(info,iChunk,iChunkBase,iChunkMapAttr);
1665 // Commit memory in the chunk for each buffer.
1668 for (TInt i=0; i<aNumBuffers ; i++)
1670 r=CommitMemoryForBuffer(offset,aBufferSize,isContiguous);
1673 r=iImageBuffer[i].Create(iChunk,offset,aBufferSize,i,isContiguous);
1674 iImageBuffer[i].iId=i;
1677 offset += (aBufferSize+pageSize);
1684 Second stage constructor for the buffer manager. This version opens an existing shared chunk using a client supplied
1685 handle. It then creates a buffer object for each buffer that exists within the chunk as well as creating a set of buffer
1686 lists to manage the buffers.
1687 @param aBufConfig The shared chunk buffer configuration object - specifying the geometry of the buffer configuration
1688 within the shared chunk supplied.
1689 @param aChunkHandle A handle for the shared chunk supplied by the client.
1690 @param anOwningThread The thread in which the given handle is valid.
1691 @return KErrNone if successful, otherwise one of the other system wide error codes.
1692 @pre The thread must be in a critical section.
1694 TInt DBufferManager::Create(TCameraSharedChunkBufConfig& aBufConfig,TInt aChunkHandle,DThread* anOwningThread)
1696 __KTRACE_CAM(Kern::Printf(">DBufferManager::Create(Handle-%d)",aChunkHandle));
1698 // Validate the buffer configuration information
1699 if (!aBufConfig.iFlags&KScFlagBufOffsetListInUse)
1700 return(KErrArgument);
1702 TInt numBuffers=aBufConfig.iNumBuffers;
1703 TInt r=CreateBufferLists(numBuffers);
1708 chunk=Kern::OpenSharedChunk(anOwningThread,aChunkHandle,ETrue);
1710 return(KErrBadHandle);
1713 // Read the physical address for the 1st buffer in order to determine the kernel address and the map attributes.
1714 TInt bufferSizeInBytes=aBufConfig.iBufferSizeInBytes;
1716 SBufSpecList* bufferSpec=&aBufConfig.iSpec;
1718 TInt offset=bufferSpec[0].iBufferOffset;
1721 r=Kern::ChunkPhysicalAddress(iChunk,offset,bufferSizeInBytes,iChunkBase,iChunkMapAttr,physAddr,NULL);
1725 // Store the supplied buffer info. into each buffer object.
1727 for (TInt i=0; i<numBuffers; i++)
1729 offset=bufferSpec[i].iBufferOffset;
1730 // Assume it isn't contiguous here - Create() will detect and do the right thing if it is contiguous.
1731 r=iImageBuffer[i].Create(iChunk,offset,bufferSizeInBytes,i,EFalse);
1732 iImageBuffer[i].iId=i;
1736 __KTRACE_CAM(Kern::Printf("<DBufferManager::Create - %d",KErrNone));
1741 Copies the contents of the Buffer Manager's configuration into aBufConfig
1742 @param aBufConfig The buffer that the data is copied into.
1744 void DBufferManager::GetBufConfig(TCameraSharedChunkBufConfig& aBufConfig)
1746 __KTRACE_CAM(Kern::Printf(">DBufferManager::GetBufConfig"));
1747 TInt numBuffers=iNumBuffers;
1751 SBufSpecList* bufferSpec=&aBufConfig.iSpec;
1753 while (numBuffers--)
1755 bufferSpec[numBuffers].iBufferOffset=iImageBuffer[numBuffers].iChunkOffset;
1756 bufferSpec[numBuffers].iBufferId=iImageBuffer[numBuffers].iId;
1759 aBufConfig.iNumBuffers=iNumBuffers;
1760 aBufConfig.iBufferSizeInBytes=iImageBuffer[0].iSize; // They're all the same size - so read from the 1st one.
1761 aBufConfig.iFlags|=KScFlagBufOffsetListInUse;
1766 Allocate an array of buffer objects, - one for each buffer contained within the shared chunk.
1767 @param aNumBuffers The number of buffer objects required.
1768 @return KErrNone if successful, otherwise one of the other system wide error codes.
1769 @pre The thread must be in a critical section.
1771 TInt DBufferManager::CreateBufferLists(TInt aNumBuffers)
1773 __KTRACE_CAM(Kern::Printf(">DBufferManager::CreateBufferLists(Bufs-%d)",aNumBuffers));
1775 // Construct the array of buffers.
1776 iNumBuffers=aNumBuffers;
1777 iImageBuffer=new TImageBuffer[aNumBuffers];
1779 return(KErrNoMemory);
1783 TInt DBufferManager::CommitMemoryForBuffer(TInt aChunkOffset,TInt aSize,TBool& aIsContiguous)
1785 __KTRACE_CAM(Kern::Printf(">DBufferManager::CommitMemoryForBuffer(Offset-%x,Sz-%d)",aChunkOffset,aSize));
1787 // Try for physically contiguous memory first.
1788 TPhysAddr physicalAddress;
1789 TInt r=Kern::ChunkCommitContiguous(iChunk,aChunkOffset,aSize,physicalAddress);
1792 aIsContiguous=ETrue;
1796 // Commit memory that isn't contiguous instead.
1797 aIsContiguous=EFalse;
1798 r=Kern::ChunkCommit(iChunk,aChunkOffset,aSize);
1803 Reset all image buffer lists to reflect the state at the start of the image capture process.
1804 @pre The buffer/request queue mutex must be held.
1806 void DBufferManager::Reset()
1808 __KTRACE_CAM(Kern::Printf(">DBufferManager::Reset"));
1812 // Before reseting buffer lists, purge the cache for all cached buffers currently in use by client.
1813 pBuf=(TImageBuffer*)iInUseBufferQ.First();
1814 SDblQueLink* anchor=&iInUseBufferQ.iA;
1815 while (pBuf!=anchor)
1818 pBuf=(TImageBuffer*)pBuf->iNext;
1821 // Start by reseting all the lists.
1822 iFreeBufferQ.iA.iNext=iFreeBufferQ.iA.iPrev=&iFreeBufferQ.iA;
1823 iCompletedBufferQ.iA.iNext=iCompletedBufferQ.iA.iPrev=&iCompletedBufferQ.iA;
1824 iInUseBufferQ.iA.iNext=iInUseBufferQ.iA.iPrev=&iInUseBufferQ.iA;
1826 // Set the pointers to the current and the next record buffers.
1827 pBuf=iImageBuffer; // This is the first buffer
1828 iCurrentBuffer=pBuf++;
1829 iNextBuffer = pBuf++;
1831 // Add all other buffers to the free list.
1832 TImageBuffer* bufferLimit=iImageBuffer+iNumBuffers;
1833 while(pBuf<bufferLimit)
1834 iFreeBufferQ.Add(pBuf++);
1838 Purge the cache for a cached image buffer.
1839 @param aBuffer The buffer to be purged.
1841 void DBufferManager::Purge(TImageBuffer* aBuffer)
1843 aBuffer->SyncMemoryBeforeDmaRead();
1847 Update buffer lists after an image has been captured.
1848 @param aResult The result of the image capture operation that has just completed.
1849 @return A pointer to the next image buffer for capture - or NULL if none are available.
1850 @pre The buffer/request queue mutex must be held.
1852 TImageBuffer* DBufferManager::SetImageCaptured(TInt aResult)
1854 // Take a copy of the buffer with the image just captured.
1855 __ASSERT_DEBUG(iCurrentBuffer,Kern::Fault(KCameraLddPanic,__LINE__));
1856 TImageBuffer* cur=iCurrentBuffer;
1858 // Make the queued buffer the current one.
1859 iCurrentBuffer=iNextBuffer;
1861 // Now we need to identify the next image buffer to queue.
1862 iNextBuffer=NextAvailableForCapture();
1864 // Now add the buffer with the image just captured to the 'completed' list.
1867 cur->iResult=aResult; // Store the result of the capture operation in the image buffer object.
1868 iCompletedBufferQ.Add(cur);
1871 __KTRACE_CAM(Kern::Printf("<DBufferManager::SetImageCaptured(buf=%08x)-%d",cur->iChunkOffset,aResult));
1872 return(iNextBuffer);
1876 Remove from the buffer lists the next buffer that is available to queue for transfer.
1877 @return A pointer to the next image buffer for capture - or NULL if none are available.
1878 @pre The buffer/request queue mutex must be held.
1880 TImageBuffer* DBufferManager::NextAvailableForCapture()
1882 // We need to identify the next image buffer to queue. Try to get one from the 'free' list.
1883 TImageBuffer* buffer=(TImageBuffer*)iFreeBufferQ.GetFirst();
1884 #ifdef DISCARD_COMPLETED_TO_AVOID_OVERFLOW
1885 // If there are none left on the 'free' list then take one from the completed list.
1887 buffer=(TImageBuffer*)iCompletedBufferQ.GetFirst();
1893 Get the next image from the 'completed' capture list. If there is no error associated with the buffer,
1894 make it 'in use' by the client. Otherwise, return the buffer to the free list.
1895 @param aRemoveLast If true, the buffer is removed from the tail of the completed capture list, otherwise
1896 it is removed from the head of this list.
1897 @return A pointer to the next completed image buffer - or NULL if there is no buffer available.
1898 @pre The buffer/request queue mutex must be held.
1900 TImageBuffer* DBufferManager::GetImageForClient(TBool aRemoveLast)
1902 __KTRACE_CAM(Kern::Printf("<DBufferManager::GetImageForClient"));
1903 TImageBuffer* buffer=NULL;
1904 if (!iCompletedBufferQ.IsEmpty())
1906 buffer = (aRemoveLast) ? (TImageBuffer*)iCompletedBufferQ.Last() : (TImageBuffer*)iCompletedBufferQ.First();
1909 if (buffer->iResult==KErrNone)
1910 iInUseBufferQ.Add(buffer);
1912 iFreeBufferQ.Add(buffer);
1918 Release (move to free list) the 'in use' image specified by the given chunk offset.
1919 @param aChunkOffset The chunk offset corresponding to the buffer to be freed.
1920 @return The freed image buffer, or NULL if no 'in use' buffer had the specified chunk offset.
1921 @return KErrNone if buffer moved to the free list;
1922 1 if the buffer needs to be queued straight away
1923 KErrArgument if no 'in use' buffer had the specified chunk offset;
1924 @pre The buffer/request queue mutex must be held.
1926 TInt DBufferManager::ReleaseImage(TInt aChunkOffset)
1928 __KTRACE_CAM(Kern::Printf(">DBufferManager::ReleaseImage(chunkOffset=%08x)",aChunkOffset));
1929 TInt r=KErrArgument;
1931 // Scan 'in use' list for the image buffer
1933 pBuf=(TImageBuffer*)iInUseBufferQ.First();
1934 SDblQueLink* anchor=&iInUseBufferQ.iA;
1935 while (pBuf!=anchor && pBuf->iChunkOffset!=aChunkOffset)
1936 pBuf=(TImageBuffer*)pBuf->iNext;
1940 // Buffer found in 'in-use' list.
1943 // We need to signal the pdd to queue this buffer straight away.
1944 iNextBuffer=(TImageBuffer*)pBuf->Deque();
1949 // Move buffer to the free list.
1950 iFreeBufferQ.Add(pBuf->Deque());
1955 __KTRACE_CAM(Kern::Printf("<DBufferManager::ReleaseImage(buf=%08x)",((pBuf!=anchor) ? pBuf->iChunkOffset : -1)));
1960 Find the 'in use' image specified by the given chunk offset
1961 @param aChunkOffset The chunk offset corresponding to the buffer to be freed
1962 @return The image buffer, or NULL if no 'in use' buffer had the specified chunk offset
1963 @pre The buffer/request queue mutex must be held.
1965 TImageBuffer* DBufferManager::FindInUseImage(TInt aChunkOffset)
1967 // Scan 'in use' list for the image buffer
1969 pBuf=(TImageBuffer*)iInUseBufferQ.First();
1970 SDblQueLink* anchor=&iInUseBufferQ.iA;
1971 while (pBuf!=anchor && pBuf->iChunkOffset!=aChunkOffset)
1972 pBuf=(TImageBuffer*)pBuf->iNext;
1974 return((pBuf!=anchor)?pBuf:NULL);
1978 Constructor for the image buffer class.
1979 Clears all member data
1981 TImageBuffer::TImageBuffer()
1983 memclr(this,sizeof(*this));
1987 Destructor for the image buffer class.
1989 TImageBuffer::~TImageBuffer()
1991 delete[] iPhysicalPages;
1995 Second stage constructor for the image buffer class - get information on the memory
1996 allocated to this buffer.
1997 @param aChunk The chunk into which the memory is to be commited
1998 @param aOffset The offset within aChunk for the start of the comitted memory.
1999 Must be a multiple of the MMU page size.
2000 @param aSize The number of bytes of memory commited.
2001 Must be a multiple of the MMU page size.
2002 @return KErrNone if successful, otherwise one of the other system wide error codes.
2003 @pre The thread must be in a critical section.
2005 TInt TImageBuffer::Create(DChunk* aChunk,TInt aOffset,TInt aSize, TInt aId, TBool aIsContiguous)
2007 __KTRACE_CAM(Kern::Printf(">TImageBuffer::Create(Off-%x,Sz-%d,Contig-%d)",aOffset,aSize,aIsContiguous));
2009 // Save info. on the chunk the buffer is in, and the offset and size of the buffer.
2011 iChunkOffset=aOffset;
2016 iPhysicalPages=NULL;
2019 // Allocate an array for a list of the physical pages.
2020 iPhysicalPages = new TPhysAddr[aSize/Kern::RoundToPageSize(1)+2];
2021 if (!iPhysicalPages)
2027 // Get the physical addresses of the pages in the buffer.
2029 r=Kern::ChunkPhysicalAddress(aChunk,aOffset,aSize,iLinearAddress,mapAttr,iPhysicalAddress,iPhysicalPages);
2030 // r = 0 or 1 on success. (1 meaning the physical pages are not contiguous).
2033 // The physical pages are not contiguous.
2034 iPhysicalAddress=KPhysAddrInvalid; // Mark the physical address as invalid.
2035 r=(aIsContiguous) ? KErrGeneral : KErrNone;
2039 delete[] iPhysicalPages; // We shouldn't retain this info. if the physical pages are contiguous.
2040 iPhysicalPages=NULL;
2043 __KTRACE_CAM(Kern::Printf("<TImageBuffer::Create - %d",r));
2048 Prepares a cacheable buffer for use by the DMA engine, before an image capture.
2050 void TImageBuffer::SyncMemoryBeforeDmaRead()
2053 if (iChunk->iMapAttr&EMapAttrCachedMax)
2055 Cache::SyncMemoryBeforeDmaRead(iLinearAddress,iSize);
2061 Prepare a cacheable buffer for use by the CPU, after an image capture using DMA.
2063 void TImageBuffer::SyncMemoryAfterDmaRead()
2066 if (iChunk->iMapAttr&EMapAttrCachedMax)
2068 Cache::SyncMemoryAfterDmaRead(iLinearAddress,iSize);
2074 Constructor for the capture request queue.
2076 TCameraScRequestQueue::TCameraScRequestQueue(NFastMutex* aMutexPtr)
2077 : iMutexPtr(aMutexPtr)
2080 memclr(&iRequest[0],sizeof(TCameraScRequest*)*KMaxCamScRequestsPending);
2084 Destructor for the capture request queue.
2086 TCameraScRequestQueue::~TCameraScRequestQueue()
2088 for (TInt i=0 ; i<KMaxCamScRequestsPending ; i++)
2093 Second stage constructor for the capture request queue.
2094 @param anOwningThread A pointer to the owning client thread.
2095 @return KErrNone if successful;
2096 KErrNoMemory if unable to allocate memory for the capture request queue.
2097 @pre The thread must be in a critical section.
2099 TInt TCameraScRequestQueue::Create(DThread* anOwningThread)
2101 iOwningThread=anOwningThread;
2103 // Create the set of available request objects and add them to the unused request queue.
2104 for (TInt i=0 ; i<KMaxCamScRequestsPending ; i++)
2106 iRequest[i]=new TCameraScRequest;
2108 return(KErrNoMemory);
2109 iUnusedRequestQ.Add(iRequest[i]);
2116 Store a request status pointer onto the tail of the capture request queue.
2117 @param aStatus The request status pointer to be stored.
2118 @return KErrNone if successful;
2119 KErrGeneral if the limit on the number of pending capture request (KMaxCamScRequestsPending) would be exceeded.
2120 @pre The buffer/request queue mutex must be held.
2122 TInt TCameraScRequestQueue::Add(TRequestStatus* aStatus)
2124 TCameraScRequest* req=(TCameraScRequest*)iUnusedRequestQ.GetFirst();
2126 return(KErrGeneral); // Must have exceeded KMaxCamScRequestsPending
2128 req->iStatus=aStatus;
2129 iPendRequestQ.Add(req);
2134 Retrieve the next request status pointer from the head of the capture request queue.
2135 @return The request status pointer removed or NULL if the list is empty.
2136 @pre The buffer/request queue mutex must be held.
2138 TRequestStatus* TCameraScRequestQueue::Remove()
2140 TRequestStatus* status=NULL;
2141 TCameraScRequest* req=(TCameraScRequest*)iPendRequestQ.GetFirst();
2144 status=req->iStatus;
2145 iUnusedRequestQ.Add(req);
2151 Remove a specifc request status pointer from the the capture request queue, completing it with a 'KErrCancel' completion reason.
2152 @param aStatus The request status pointer to be completed.
2153 @pre The buffer/request queue mutex must be held.
2155 void TCameraScRequestQueue::Cancel(TRequestStatus* aStatus)
2157 // Find the entry concerned
2158 TCameraScRequest* req=(TCameraScRequest*)iPendRequestQ.First();
2159 SDblQueLink* anchor=&iPendRequestQ.iA;
2160 while (req!=anchor && req->iStatus!=aStatus)
2161 req=(TCameraScRequest*)req->iNext;
2165 // Remove and cancel it.
2167 iUnusedRequestQ.Add(req);
2168 NKern::FMSignal(iMutexPtr); // Release the request list mutex while we complete the request. This is safe.
2169 Kern::RequestComplete(iOwningThread,req->iStatus,KErrCancel);
2170 NKern::FMWait(iMutexPtr); // Re-acquire the request list mutex.
2174 Remove each request status pointer from the the capture request queue, completing each with a 'KErrCancel' completion reason.
2175 @pre The buffer/request queue mutex must be held.
2177 void TCameraScRequestQueue::CancelAll()
2180 TRequestStatus* status;
2181 while ((status=Remove())!=NULL)
2183 NKern::FMSignal(iMutexPtr); // Release the request list mutex while we complete the request. This is safe.
2184 Kern::RequestComplete(iOwningThread,status,KErrCancel);
2185 NKern::FMWait(iMutexPtr); // Re-acquire the request list mutex.
2190 Constructor for the camera driver power handler class.
2191 @param aChannel A pointer to the camera driver logical channel which owns this power handler.
2193 DCameraScPowerHandler::DCameraScPowerHandler(DCameraScLdd* aChannel)
2194 : DPowerHandler(KDevCameraScName),
2200 A request from the power manager for the power down of the camera device.
2201 This is called during a transition of the phone into standby or power off.
2202 @param aState The target power state; can be EPwStandby or EPwOff only.
2204 void DCameraScPowerHandler::PowerDown(TPowerState aPowerState)
2207 __KTRACE_CAM(Kern::Printf(">DCameraScPowerHandler::PowerDown(State-%d)",aPowerState));
2209 // Power-down involves hardware access so queue a DFC to perform this from the driver thread.
2210 iChannel->iPowerDownDfc.Enque();
2214 A request from the power manager for the power up of the camera device.
2215 This is called during a transition of the phone out of standby.
2217 void DCameraScPowerHandler::PowerUp()
2219 __KTRACE_CAM(Kern::Printf(">DCameraScPowerHandler::PowerUp"));
2221 // Power-up involves hardware access so queue a DFC to perform this from the driver thread.
2222 iChannel->iPowerUpDfc.Enque();