os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/camerasc/camerasc.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    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
    17 // 
    18 //
    19 #include "camerasc_plat.h"
    20 
    21 _LIT(KCameraScPddName, "CameraSc.TE");
    22 _LIT(KCameraScDfcQueueName, "CameraSc.TE.DfcQ");
    23 
    24 /**
    25 Standard export function for PDD factories.  This creates a DPhysicalDevice derived object, in this case,
    26 DTemplateCameraScPddFactory.
    27 */
    28 DECLARE_STANDARD_PDD()
    29 	{
    30 	return new DTemplateCameraScPddFactory;
    31 	}
    32 
    33 /**
    34 Constructor for the shared chunk camera PDD factory class.
    35 */
    36 DTemplateCameraScPddFactory::DTemplateCameraScPddFactory()
    37 	{
    38 	// We currently support only unit 0
    39 	iUnitsMask = 0x01;
    40 
    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();
    45 	}
    46 
    47 /**
    48 Destructor for the shared chunk camera PDD factory class.
    49 */
    50 DTemplateCameraScPddFactory::~DTemplateCameraScPddFactory()
    51 	{
    52 	}
    53 
    54 /**
    55 Second stage constructor for the shared chunk camera PDD factory class.  This must at least set a name for
    56 the driver object.
    57 @return KErrNone if successful, otherwise one of the system wide error codes.
    58 */
    59 TInt DTemplateCameraScPddFactory::Install()
    60 	{
    61 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Install()"));
    62 
    63 	TInt r;
    64 
    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)
    68 		{
    69 		// All PDD factories must have a unique name
    70 		r = SetName(&KCameraScPddName);
    71 		}
    72 
    73 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Install() => Returning %d", r));
    74 
    75 	return r;
    76 	}
    77 
    78 /**
    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.
    82 */
    83 void DTemplateCameraScPddFactory::GetCaps(TDes8& /*aDes*/) const
    84 	{
    85 	}
    86 
    87 /**
    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.
    97 */
    98 TInt DTemplateCameraScPddFactory::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
    99 	{
   100 	// Check that the version requested is less than or equal to the version of this PDD
   101 	if (!Kern::QueryVersionSupported(RDevCameraSc::VersionRequired(), aVer))
   102 		{
   103 		return KErrNotSupported;
   104 		}
   105 
   106 	// Check that the unit number specifies the available sensor
   107 	if ((aUnit < 0) || (aUnit > 0))
   108 		{
   109 		return KErrNotSupported;
   110 		}
   111 
   112 	return KErrNone;
   113 	}
   114 
   115 /**
   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.
   124 */
   125 TInt DTemplateCameraScPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
   126 	{
   127 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPddFactory::Create()"));
   128 
   129 	// Create an instance of the PDD channel object that will work with the Template sensor
   130 	DTemplateCameraScPdd* pD = new DTemplateCameraScPdd;
   131 
   132 	aChannel = pD;
   133 	TInt r = KErrNoMemory;
   134 
   135 	if (pD)
   136 		{
   137 		r = pD->DoCreate(this, aUnit);
   138 		}
   139 
   140 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPddFactory::Create() => Returning %d", r));
   141 
   142 	return r;
   143 	}
   144 
   145 /**
   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.
   150 */
   151 TBool DTemplateCameraScPddFactory::IsUnitOpen(TInt aUnit)
   152 	{
   153 	return (iUnitsOpenMask & (1 << aUnit));
   154 	}
   155 
   156 /**
   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.
   163 */
   164 TInt DTemplateCameraScPddFactory::SetUnitOpen(TInt aUnit, TBool aIsOpen)
   165 	{
   166 	// Wait until it is safe to access the unit state mask
   167 	NKern::FMWait(&iUnitInfoMutex);
   168 
   169 	// Fail a request to open a unit that is already open
   170 	if (aIsOpen && IsUnitOpen(aUnit))
   171 		{
   172 		__KTRACE_CAM(Kern::Printf("+ DTemplateCameraScPddFactory::SetUnitOpen() => Unit %d is already in use", aUnit));
   173 
   174 		// Release the unit state mask mutex
   175 		NKern::FMSignal(&iUnitInfoMutex);
   176 
   177 		return KErrInUse;
   178 		}
   179 
   180 	// Set or clear the unit's open status bit as required
   181 	if (aIsOpen)
   182 		{
   183 		iUnitsOpenMask |= (1 << aUnit);
   184 		}
   185 	else
   186 		{
   187 		iUnitsOpenMask &= ~(1 << aUnit);
   188 		}
   189 
   190 	// Release the unit state mask mutex
   191 	NKern::FMSignal(&iUnitInfoMutex);
   192 
   193 	return KErrNone;
   194 	}
   195 
   196 /**
   197 Constructor for the shared chunk camera PDD class.
   198 */
   199 DTemplateCameraScPdd::DTemplateCameraScPdd()
   200 	{
   201 	// Set the unit number to -1 to indicate that this channel has never been registered
   202 	// with the PDD factory
   203 	iUnit = -1;
   204 
   205 	// The channel has been created but not yet configured */
   206 	iState = EUnconfigured;
   207 	}
   208 
   209 /**
   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.
   212 */
   213 DTemplateCameraScPdd::~DTemplateCameraScPdd()
   214 	{
   215 	delete [] iCapsBuffer;
   216 	delete iSensor;
   217 
   218 	// Indicate that a physical channel is no longer open on this unit
   219 	if (iUnit >= 0)
   220 		{
   221 		iPhysicalDevice->SetUnitOpen(iUnit, EFalse);
   222 		}
   223 	}
   224 
   225 /**
   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.
   230 */
   231 TInt DTemplateCameraScPdd::DoCreate(DTemplateCameraScPddFactory* aPhysicalDevice, TInt aUnit)
   232 	{
   233 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::DoCreate()"));
   234 
   235 	TInt r;
   236 
   237 	iPhysicalDevice = aPhysicalDevice;
   238 
   239 	// Check that a physical channel hasn't already been opened on this unit
   240 	if ((r = iPhysicalDevice->SetUnitOpen(aUnit, ETrue)) == KErrNone)
   241 		{
   242 		iUnit = aUnit;
   243 
   244 		// Create an abstracted sensor interface
   245 		if ((iSensor = new DTemplateSensorIf(*this, DfcQ(aUnit))) != NULL)
   246 			{
   247 			if ((r = iSensor->DoCreate()) == KErrNone)
   248 				{
   249 				// Setup the capabilities of this device for later reference
   250 				if ((r = iSensor->GetCaps(iCaps)) > 0)
   251 					{
   252 					// And save the size as returned from the sensor
   253 					iCapsSize = r;
   254 
   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;
   259 
   260 					// Enable the clocks needed by the camera subsystem and power up the sensor
   261 					r = iSensor->RequestPower();
   262 
   263 					// Some sensors power themselves up automatically in their DoCreate() function,
   264 					// so take this into account here
   265 					if (r == KErrAlreadyExists)
   266 						{
   267 						r = KErrNone;
   268 						}
   269 					}
   270 				}
   271 			}
   272 		else
   273 			{
   274 			r = KErrNoMemory;
   275 			}
   276 		}
   277 
   278 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::DoCreate() => Returning %d", r));
   279 
   280 	return r;
   281 	}
   282 
   283 /**
   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.
   290 */
   291 TDfcQue* DTemplateCameraScPdd::DfcQ(TInt /*aUnit*/)
   292 	{
   293 	return iPhysicalDevice->iDfcQ;
   294 	}
   295 
   296 /**
   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.
   300 */
   301 void DTemplateCameraScPdd::Caps(TDes8& aCapsBuf) const
   302 	{
   303 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Caps()"));
   304 
   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()));
   311 
   312 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Caps()"));
   313 	}
   314 
   315 /**
   316 Called by the LDD to setup a new image configuration, including such things as image size, framerate
   317 and pixel format.
   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.
   320 */
   321 TInt DTemplateCameraScPdd::SetConfig(const TDesC8& aConfigBuf)
   322 	{
   323 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::SetConfig()"));
   324 
   325 	TInt r;
   326 
   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)
   330 		{
   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);
   337 
   338 		// Save the new configuration for later and let the sensor also know about it
   339 		iConfig = config;
   340 		iSensor->SetConfig(config);
   341 
   342 		// Signal success and set the channel to the configured state
   343 		r = KErrNone;
   344 		iState = EConfigured;
   345 		}
   346 	else
   347 		{
   348 		r = KErrInUse;
   349 		}
   350 
   351 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::SetConfig() => Returning %d", r));
   352 
   353 	return r;
   354 	}
   355 
   356 /**
   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.
   364 */
   365 TInt DTemplateCameraScPdd::Start(TDevCamCaptureMode aCaptureMode, TLinAddr aLinAddr, TPhysAddr aPhysAddr)
   366 	{
   367 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Start() => Configuring sensor for %d x %d capture", iConfig.iFrameSize.iWidth, iConfig.iFrameSize.iHeight));
   368 
   369 	// Ensure the precondition is met
   370 	__ASSERT_DEBUG((iState == EConfigured), Kern::Fault("camerasc", ENotConfigured));
   371 
   372 	// Save the capture mode for use when we call back into the LDD with the captured image
   373 	iCaptureMode = aCaptureMode;
   374 
   375 	// And start the sensor running
   376 	TInt r = iSensor->Start(aCaptureMode, aLinAddr, aPhysAddr);
   377 
   378 	// If everything was ok, set the channel to the capturing state
   379 	if (r == KErrNone)
   380 		{
   381 		iState = ECapturing;
   382 		}
   383 
   384 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Start() => Returning %d", r));
   385 
   386 	return r;
   387 	}
   388 
   389 /**
   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.
   395 */
   396 TInt DTemplateCameraScPdd::CaptureNextImage(TLinAddr aLinAddr, TPhysAddr aPhysAddr)
   397 	{
   398 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::CaptureNextImage()"));
   399 
   400 	// Pass the call directly to the sensor abstraction
   401 	TInt r = iSensor->CaptureNextImage(aLinAddr, aPhysAddr);
   402 
   403 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::CaptureNextImage()=> Returning %d", r));
   404 
   405 	return(r);
   406 	}
   407 
   408 /**
   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.
   411 */
   412 TInt DTemplateCameraScPdd::Stop()
   413 	{
   414 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::Stop()"));
   415 
   416 	// Pass the call directly to the sensor abstraction
   417 	iSensor->Stop();
   418 
   419 	// Det the channel back to the configured state as it is now safe to call Start() again
   420 	iState = EConfigured;
   421 
   422 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::Stop()"));
   423 
   424 	return KErrNone;
   425 	}
   426 
   427 /**
   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.
   430 */
   431 void DTemplateCameraScPdd::PowerDown()
   432 	{
   433 
   434 #ifdef _DEBUG
   435 
   436 	// Power off the camera
   437 	TInt r = iSensor->RelinquishPower();
   438 
   439 	// Not being able to power down indicates a serious programming error
   440 	__ASSERT_DEBUG((r == KErrNone), Kern::Fault("camerasc", ECannotPowerDown));
   441 
   442 #else // ! _DEBUG
   443 
   444 	// Power off the camera
   445 	iSensor->RelinquishPower();
   446 
   447 #endif // ! _DEBUG
   448 
   449 	}
   450 
   451 /**
   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.
   454 */
   455 void DTemplateCameraScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)
   456 	{
   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
   460 #ifdef __WINS__
   461 	aChunkCreateInfo.iMapAttr = 0xFF000;
   462 #else
   463 	aChunkCreateInfo.iMapAttr = EMapAttrCachedMax;
   464 #endif
   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;
   469 	}
   470 
   471 /**
   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.
   476 */
   477 TInt DTemplateCameraScPdd::CapsSize()
   478 	{
   479 	return iCapsSize;
   480 	}
   481 
   482 /**
   483 Obtains information regarding the frame sizes and frame rates supported for a given combination of capture mode
   484 and pixel format.
   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.
   490 */
   491 TInt DTemplateCameraScPdd::FrameSizeCaps(TDevCamCaptureMode aCaptureMode, TUidPixelFormat aUidPixelFormat, TDes8& aFrameSizeCapsBuf)
   492 	{
   493 	return iSensor->FrameSizeCaps(aCaptureMode, aUidPixelFormat, aFrameSizeCapsBuf);
   494 	}
   495 
   496 /**
   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.
   501 */
   502 TInt DTemplateCameraScPdd::NotifyImageCaptureEvent(TInt aResult, TLinAddr& aLinAddr, TPhysAddr& aPhysAddr)
   503 	{
   504 	__KTRACE_CAM(Kern::Printf("> DTemplateCameraScPdd::NotifyImageCaptureEvent() => aResult = %d", aResult));
   505 
   506 	// Inform the LDD that a new image has been received
   507 	TInt r = iLdd->ImageCaptureCallback(iCaptureMode, aResult, &aLinAddr, &aPhysAddr);
   508 
   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()
   511 	if (r != KErrNone)
   512 		{
   513 		Stop();
   514 		}
   515 
   516 	__KTRACE_CAM(Kern::Printf("< DTemplateCameraScPdd::NotifyImageCaptureEvent() => Returning %d", r));
   517 
   518 	return r;
   519 	}
   520 
   521 TInt DTemplateCameraScPdd::SetBrightness(TUint /*aBrightness*/)
   522 	{
   523 	return KErrNone;
   524 	}
   525 
   526 TInt DTemplateCameraScPdd::SetContrast(TUint /*aContrast*/)
   527 	{
   528 	return KErrNone;
   529 	}
   530 
   531 TInt DTemplateCameraScPdd::SetColorEffect(TUint /*aColorEffect*/)
   532 	{
   533 	return KErrNone;
   534 	}
   535