Update contrib.
1 // Copyright (c) 2006-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 // template\template_variant\camerasc\camerasc.cpp
15 // Implementation of the template shared chunk camera physical device driver (PDD).
16 // This file is part of the Template Base port
19 #include "camerasc_plat.h"
21 _LIT(KCameraScPddName, "CameraSc.TE");
22 _LIT(KCameraScDfcQueueName, "CameraSc.TE.DfcQ");
25 Standard export function for PDD factories. This creates a DPhysicalDevice derived object, in this case,
26 DTemplateCameraScPddFactory.
28 DECLARE_STANDARD_PDD()
30 return new DTemplateCameraScPddFactory;
34 Constructor for the shared chunk camera PDD factory class.
36 DTemplateCameraScPddFactory::DTemplateCameraScPddFactory()
38 // We currently support only unit 0
41 // Set the version number for this device. This is used to allow code to specify that it requires a
42 // minimum version of the device in order to operate. If the version requested is less than this then
43 // the device is safe to be used
44 iVersion = RDevCameraSc::VersionRequired();
48 Destructor for the shared chunk camera PDD factory class.
50 DTemplateCameraScPddFactory::~DTemplateCameraScPddFactory()
55 Second stage constructor for the shared chunk camera PDD factory class. This must at least set a name for
57 @return KErrNone if successful, otherwise one of the system wide error codes.
59 TInt DTemplateCameraScPddFactory::Install()
61 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Install()"));
65 // Create a DFC queue so that handling of both camera hardware callbacks and requests made to the LDD from
66 // user mode can be processed in the same thread, to avoid the use of semaphores
67 if ((r = Kern::DynamicDfcQCreate(iDfcQ, 26, KCameraScDfcQueueName)) == KErrNone)
69 // All PDD factories must have a unique name
70 r = SetName(&KCameraScPddName);
73 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Install() => Returning %d", r));
79 Returns the PDD's capabilities. This is not used by the Symbian OS device driver framework
80 or by the LDD but is here as some LDDs will make use of it.
81 @param aDes A descriptor into which to write capability information.
83 void DTemplateCameraScPddFactory::GetCaps(TDes8& /*aDes*/) const
88 Called by the kernel's device driver framework to check if this PDD is suitable for use
89 with a logical channel. This is called in the context of the client thread which requested
90 the creation of a logical channel, through a call to RBusLogicalChannel::DoCreate(). The
91 thread is in a critical section.
92 @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate()
93 This is used to determine which sensor to use.
94 @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate().
95 @param aVer The version number of the logical channel which will use this physical channel.
96 @return KErrNone if successful, otherwise one of the system wide error codes.
98 TInt DTemplateCameraScPddFactory::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
100 // Check that the version requested is less than or equal to the version of this PDD
101 if (!Kern::QueryVersionSupported(RDevCameraSc::VersionRequired(), aVer))
103 return KErrNotSupported;
106 // Check that the unit number specifies the available sensor
107 if ((aUnit < 0) || (aUnit > 0))
109 return KErrNotSupported;
116 Called by the kernel's device driver framework to create a physical channel object. This
117 is called in the context of the client thread which requested the creation of a logical
118 channel, through a call to RBusLogicalChannel::DoCreate(). The thread is in a critical section.
119 @param aChannel Set by this function to point to the created physical channel object.
120 @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate().
121 @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate().
122 @param aVer The version number of the logical channel which will use this physical channel.
123 @return KErrNone if successful, otherwise one of the other system wide error codes.
125 TInt DTemplateCameraScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
127 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Create()"));
129 // Create an instance of the PDD channel object that will work with the Template sensor
130 DTemplateCameraScPdd* pD = new DTemplateCameraScPdd;
133 TInt r = KErrNoMemory;
137 r = pD->DoCreate(this, aUnit);
140 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Create() => Returning %d", r));
146 Called by SetUnitOpen() to see if a particular unit is open. When called, the
147 iUnitInfoMutex fast mutex will be taken, ensuring safe access to iUnitsOpenMask.
148 @param aUnit The unit number to be checked for being open.
149 @return ETrue if the unit specified by aUnit is already open, otherwise EFalse.
151 TBool DTemplateCameraScPddFactory::IsUnitOpen(TInt aUnit)
153 return (iUnitsOpenMask & (1 << aUnit));
157 Attempt to change the state of the unit open state for a particular unit.
158 @param aUnit The unit number to be set to open or closed state.
159 @param aIsOpen The required new state for the unit; either ETrue to set the state
160 to open or EFalse to set the state to closed.
161 @return KErrNone if the state was updated successfully, otherwise KErrInUse if an attempt
162 was made to set the unit status to open while it is already open.
164 TInt DTemplateCameraScPddFactory::SetUnitOpen(TInt aUnit, TBool aIsOpen)
166 // Wait until it is safe to access the unit state mask
167 NKern::FMWait(&iUnitInfoMutex);
169 // Fail a request to open a unit that is already open
170 if (aIsOpen && IsUnitOpen(aUnit))
172 __KTRACE_CAM(Kern::Printf("+ DTemplateCameraScPddFactory::SetUnitOpen() => Unit %d is already in use", aUnit));
174 // Release the unit state mask mutex
175 NKern::FMSignal(&iUnitInfoMutex);
180 // Set or clear the unit's open status bit as required
183 iUnitsOpenMask |= (1 << aUnit);
187 iUnitsOpenMask &= ~(1 << aUnit);
190 // Release the unit state mask mutex
191 NKern::FMSignal(&iUnitInfoMutex);
197 Constructor for the shared chunk camera PDD class.
199 DTemplateCameraScPdd::DTemplateCameraScPdd()
201 // Set the unit number to -1 to indicate that this channel has never been registered
202 // with the PDD factory
205 // The channel has been created but not yet configured */
206 iState = EUnconfigured;
210 Destructor for the shared chunk camera PDD class. This is called in the context of the client thread
211 once an 'ECloseMsg' message has been sent to the device driver DFC thread.
213 DTemplateCameraScPdd::~DTemplateCameraScPdd()
215 delete [] iCapsBuffer;
218 // Indicate that a physical channel is no longer open on this unit
221 iPhysicalDevice->SetUnitOpen(iUnit, EFalse);
226 Second stage constructor for the H4 camera PDD.
227 @param aPhysicalDevice A pointer to the factory class that is creating this PDD
228 @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate().
229 @return KErrNone if successful, otherwise one of the other system wide error codes.
231 TInt DTemplateCameraScPdd::DoCreate(DTemplateCameraScPddFactory* aPhysicalDevice, TInt aUnit)
233 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::DoCreate()"));
237 iPhysicalDevice = aPhysicalDevice;
239 // Check that a physical channel hasn't already been opened on this unit
240 if ((r = iPhysicalDevice->SetUnitOpen(aUnit, ETrue)) == KErrNone)
244 // Create an abstracted sensor interface
245 if ((iSensor = new DTemplateSensorIf(*this, DfcQ(aUnit))) != NULL)
247 if ((r = iSensor->DoCreate()) == KErrNone)
249 // Setup the capabilities of this device for later reference
250 if ((r = iSensor->GetCaps(iCaps)) > 0)
252 // And save the size as returned from the sensor
255 // Although iCaps now points to a TCameraCapsV02 structure, it is actually a variable
256 // sized structure that was allocated as an array of TUint8 so save it to a TUint8
257 // ptr so that it can be deleted properly
258 iCapsBuffer = (TUint8*) iCaps;
260 // Enable the clocks needed by the camera subsystem and power up the sensor
261 r = iSensor->RequestPower();
263 // Some sensors power themselves up automatically in their DoCreate() function,
264 // so take this into account here
265 if (r == KErrAlreadyExists)
278 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::DoCreate() => Returning %d", r));
284 An appropriate DFC queue to use for processing client requests (that is, those that won't be processed
285 in the context of the client thread), and also for processing image completion requests from the sensor
286 will have been setup by the PDD factory. Anything needing to run in this same DFC thread can access the
287 queue via this function.
288 @param aUnit The unit number for which to get the DFC queue.
289 @return The DFC queue to be used.
291 TDfcQue* DTemplateCameraScPdd::DfcQ(TInt /*aUnit*/)
293 return iPhysicalDevice->iDfcQ;
297 Called by the LDD in order to query the capabilities of the PDD.
298 @param aCapsBuf A reference to a descriptor owned by the LDD, containing a TCameraCapsV02 structure
299 for the capabilities.
301 void DTemplateCameraScPdd::Caps(TDes8& aCapsBuf) const
303 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Caps()"));
305 // The iCaps structure will already have been created by a call to iSensor->SetCaps() in DoCreate().
306 // Simply copy it into the supplied TPckgBuf, taking into account the fact that the TCameraCapsV02
307 // buffer is of a variable size *and* may be smaller or larger than the iCaps structure
308 TPtrC8 ptr((const TUint8*) iCaps, iCapsSize);
309 aCapsBuf.FillZ(aCapsBuf.MaxLength());
310 aCapsBuf = ptr.Left(Min(ptr.Length(), aCapsBuf.MaxLength()));
312 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Caps()"));
316 Called by the LDD to setup a new image configuration, including such things as image size, framerate
318 @param aConfigBuf A reference to a TPckgBuf containing a TCameraConfigV02 configuration structure.
319 @return KErrNone if successful, otherwise one of the system wide error codes.
321 TInt DTemplateCameraScPdd::SetConfig(const TDesC8& aConfigBuf)
323 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::SetConfig()"));
327 // It is only legal to call this if image capture is not already underway, so check for this
328 // before doing anything
329 if (iState <= EConfigured)
331 // Read the new configuration from the LDD into a local copy of the configuration structure,
332 // taking into account for compatibility that the TPckgBuf may be smaller or larger than the
333 // TCameraConfigV02 structure
334 TCameraConfigV02 config;
335 TPtr8 ptr((TUint8*) &config, sizeof(config));
336 Kern::InfoCopy(ptr, aConfigBuf);
338 // Save the new configuration for later and let the sensor also know about it
340 iSensor->SetConfig(config);
342 // Signal success and set the channel to the configured state
344 iState = EConfigured;
351 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::SetConfig() => Returning %d", r));
357 Begins capture into the address pointed to by aLinAddr and aPhysAddr. Both of these addresses point to
358 the same buffer; The address used by the sensor is hardware dependent.
359 @param aCaptureMode Whether to capture in video, viewfinder or single image mode.
360 @param aLinAddr The virtual address of the buffer into which to capture the image.
361 @param aPhysAddr The physical address of the buffer into which to capture the image.
362 @return KErrNone if successful, otherwise one of the other system wide error codes.
363 @pre SetConfig() must first have been called.
365 TInt DTemplateCameraScPdd::Start(TDevCamCaptureMode aCaptureMode, TLinAddr aLinAddr, TPhysAddr aPhysAddr)
367 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Start() => Configuring sensor for %d x %d capture", iConfig.iFrameSize.iWidth, iConfig.iFrameSize.iHeight));
369 // Ensure the precondition is met
370 __ASSERT_DEBUG((iState == EConfigured), Kern::Fault("camerasc", ENotConfigured));
372 // Save the capture mode for use when we call back into the LDD with the captured image
373 iCaptureMode = aCaptureMode;
375 // And start the sensor running
376 TInt r = iSensor->Start(aCaptureMode, aLinAddr, aPhysAddr);
378 // If everything was ok, set the channel to the capturing state
384 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Start() => Returning %d", r));
390 Sets the address of the buffer info which the next image will be captured. Called by the LDD for successive
391 images that are requested after the initial call to Start().
392 @param aLinAddr The virtual address of the buffer into which to capture the image.
393 @param aPhysAddr The physical address of the buffer into which to capture the image.
394 @return KErrNone if successful, otherwise one of the other system wide error codes.
396 TInt DTemplateCameraScPdd::CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr)
398 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::CaptureNextImage()"));
400 // Pass the call directly to the sensor abstraction
401 TInt r = iSensor->CaptureNextImage(aLinAddr, aPhysAddr);
403 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::CaptureNextImage()=> Returning %d", r));
409 Stops any image capturing that is currently underway. It is safe to call this without having called Start().
410 @return KErrNone if successful, otherwise one of the other system wide error codes.
412 TInt DTemplateCameraScPdd::Stop()
414 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Stop()"));
416 // Pass the call directly to the sensor abstraction
419 // Det the channel back to the configured state as it is now safe to call Start() again
420 iState = EConfigured;
422 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Stop()"));
428 Power down the camera device. This is called by the LDD when the driver channel is being closed or
429 when the system is being powered down. This is always called in the context of the DFC thread.
431 void DTemplateCameraScPdd::PowerDown()
436 // Power off the camera
437 TInt r = iSensor->RelinquishPower();
439 // Not being able to power down indicates a serious programming error
440 __ASSERT_DEBUG((r == KErrNone), Kern::Fault("camerasc", ECannotPowerDown));
444 // Power off the camera
445 iSensor->RelinquishPower();
452 Return the shared chunk creation information to be used by this device.
453 @param aChunkCreateInfo A structure to be filled with the settings required for this device.
455 void DTemplateCameraScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)
457 // Can be opened by any number of user side processes
458 aChunkCreateInfo.iType = TChunkCreateInfo::ESharedKernelMultiple;
459 // Use both L1 and L2 cache if available. LDD will take care of pre and post DMA cache handling
461 aChunkCreateInfo.iMapAttr = 0xFF000;
463 aChunkCreateInfo.iMapAttr = EMapAttrCachedMax;
465 // Chunk owns the memory which will be freed when the chunk is destroyed
466 aChunkCreateInfo.iOwnsMemory = ETrue;
467 // Don't queue the chunk's destruction on an DFC
468 aChunkCreateInfo.iDestroyedDfc = NULL;
472 Returns the size of the variable sized capabilities structure in bytes. The buffer passed into
473 DTemplateCameraScPdd::GetCaps() must be at least this large to hold the fixed portion of the TCameraCapsV02
474 structure, as well as the array of SDevCamPixelFormat structures that follows it.
475 @return The size in bytes of the variable sized capabilities structure.
477 TInt DTemplateCameraScPdd::CapsSize()
483 Obtains information regarding the frame sizes and frame rates supported for a given combination of capture mode
485 @param aCaptureMode The capture mode for which to obtain the information.
486 @param aUidPixelFormat The pixel format for which to obtain the information.
487 @param aFrameSizeCapsBuf A reference to an array of packaged SDevCamFrameSize structures, owned by the LDD, into
488 which to place the information.
489 @@return KErrNone if successful, else one of the other system wide error codes.
491 TInt DTemplateCameraScPdd::FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf)
493 return iSensor->FrameSizeCaps(aCaptureMode, aUidPixelFormat, aFrameSizeCapsBuf);
497 Called by the sensor abstraction when an image is available.
498 @param aResult KErrNone if successful, otherwise one of the system wide error codes.
499 @param aLinAddr The virtual address of the buffer into which to capture the image.
500 @param aPhysAddr The physical address of the buffer into which to capture the image.
502 TInt DTemplateCameraScPdd::NotifyImageCaptureEvent(TInt aResult, TLinAddr& aLinAddr, TPhysAddr& aPhysAddr)
504 __KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::NotifyImageCaptureEvent() => aResult = %d", aResult));
506 // Inform the LDD that a new image has been received
507 TInt r = iLdd->ImageCaptureCallback(iCaptureMode, aResult, &aLinAddr, &aPhysAddr);
509 // If the LDD has returned KErrAbort then something has gone wrong, and if it has returned KErrNotReady
510 // then it has no more frames available, so call Stop()
516 __KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::NotifyImageCaptureEvent() => Returning %d", r));
521 TInt DTemplateCameraScPdd::SetBrightness(TUint /*aBrightness*/)
526 TInt DTemplateCameraScPdd::SetContrast(TUint /*aContrast*/)
531 TInt DTemplateCameraScPdd::SetColorEffect(TUint /*aColorEffect*/)