os/kernelhwsrv/bsptemplate/asspandvariant/template_assp/gpio.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description:
    15 *
    16 */
    17 #include <kernel/kern_priv.h>
    18 #include <template_assp.h>
    19 #include <drivers/gpio.h>
    20 
    21 const TInt32		KHwGpioPinMax		= 0;	// TO DO: max pin number this GPIO chip supports
    22 const TInt32		KIntIdGpio		= 0;	// TO DO: need to define which interrupt the GPIO chip is attached to
    23 
    24 //
    25 // TO DO: if the GPIO chip doesn't support specific features
    26 // such as debouncing or pin modes, then it may be
    27 // necessary to store them ourselves in an array of GpioPins
    28 // other features such as pin bias or idle configurations
    29 // may be left as KErrNotSupported
    30 //
    31 class GpioPin
    32 	{
    33 public:
    34    	TGpioIsr		iIsr;	// e.g. we may want to remeber the isr attached to a pin
    35 	TAny *			iPtr;	// argument to pass to isr
    36 	};
    37 
    38 static GpioPin	GpioPins[KHwGpioPinMax+1];
    39 
    40 static TInt32	GpioInterruptId; // place to store interrupt handle returned from Interrupt::Bind()
    41 
    42 /**
    43 GPIO interrupt handler
    44 generic argument (TAny*) is a pointer to the GpioPins array
    45 */
    46 void GpioIsrDispatch(TAny *aPtr)
    47 	{
    48 	// TO DO: work out which pins have interrupts pending
    49 	// and dispatch the appropriate ISR
    50 	GpioPin	*pins = (GpioPin *)aPtr;
    51 	TUint32 interrupt = 0xff; // TO DO: read gpio pending interupts
    52 	TUint32 enabled = 0x00; // TO DO: read gpio enabled interupts
    53 	TUint32	masked = interrupt & enabled; // TO DO: read masked interrupts
    54 
    55 	// check each pin and dispatch ISR if necessary
    56 	for (TInt i = 0; i <= KHwGpioPinMax; i++)
    57 		{
    58 		if ((masked & 0x1) && (pins[i].iIsr != NULL))
    59 			{
    60 			// we have a pending interrupt and a registered ISR
    61 			(*pins[i].iIsr)(pins[i].iPtr); // dispatch this pin's ISR
    62 			}
    63 		masked >>= 1;
    64 		}
    65 	Interrupt::Clear(GpioInterruptId);
    66 	}
    67 
    68 
    69 EXPORT_C TInt GPIO::SetPinMode
    70 	(
    71 	TInt      aId,
    72    	TGpioMode aMode
    73 	)
    74 	{
    75 	if (aId < 0 || aId > KHwGpioPinMax)
    76 		{
    77 		return KErrArgument;
    78 		}
    79 	// TO DO: store pin mode and return
    80 	return KErrNone;
    81 	}
    82 
    83 EXPORT_C TInt GPIO::GetPinMode
    84 	(
    85 	TInt        aId,
    86    	TGpioMode & aMode
    87 	)
    88 	{
    89 	if (aId < 0 || aId > KHwGpioPinMax)
    90 		{
    91 		return KErrArgument;
    92 		}
    93 	// TO DO: set aMode = pin mode
    94 	return KErrNone;
    95 	}
    96 
    97 EXPORT_C TInt GPIO::SetPinDirection
    98 	(
    99 	TInt           aId,
   100    	TGpioDirection aDirection
   101 	)
   102 	{
   103 	if (aId < 0 || aId > KHwGpioPinMax || aDirection == ETriStated)
   104 		{
   105 		return KErrArgument;
   106 		}
   107 	// TO DO: if we support setting the pin direction then do it here
   108 	return KErrNone;
   109 	}
   110 
   111 EXPORT_C TInt GPIO::GetPinDirection
   112 	(
   113 	TInt             aId,
   114    	TGpioDirection & aDirection
   115 	)
   116 	{
   117 	if (aId < 0 || aId > KHwGpioPinMax)
   118 		{
   119 		return KErrArgument;
   120 		}
   121 	// TO DO: if we support getting the pin direction then do it here
   122 	return KErrNone;
   123 	}
   124 
   125 EXPORT_C TInt GPIO::SetPinBias
   126 	(
   127 	TInt      aId,
   128    	TGpioBias aBias
   129 	)
   130 	{
   131 	if (aId < 0 || aId > KHwGpioPinMax)
   132 		{
   133 		return KErrArgument;
   134 		}
   135 	// TO DO: if we support setting the pin bias then do it here
   136 	return KErrNone;
   137 	}
   138 
   139 EXPORT_C TInt GPIO::GetPinBias
   140 	(
   141 	TInt        aId,
   142    	TGpioBias & aBias
   143 	)
   144 	{
   145 	if (aId < 0 || aId > KHwGpioPinMax)
   146 		{
   147 		return KErrArgument;
   148 		}
   149 	// TO DO: if we support getting the pin bias then do it here
   150 	return KErrNone;
   151 	}
   152 
   153 EXPORT_C TInt GPIO::SetPinIdleConfigurationAndState
   154 	(
   155 	TInt        aId,
   156    	TInt		/*aConf*/
   157 	)
   158 	{
   159 	if (aId < 0 || aId > KHwGpioPinMax)
   160 		{
   161 		return KErrArgument;
   162 		}
   163 	// TO DO: if we support setting the pin idle config then do it here
   164 	return KErrNone;
   165 	}
   166 
   167 EXPORT_C TInt GPIO::GetPinIdleConfigurationAndState
   168 	(
   169 	TInt        aId,
   170    	TInt	  & aBias
   171 	)
   172 	{
   173 	if (aId < 0 || aId > KHwGpioPinMax)
   174 		{
   175 		return KErrArgument;
   176 		}
   177 	// TO DO: if we support getting the pin idle config then do it here
   178 	return KErrNone;
   179 	}
   180 
   181 EXPORT_C TInt GPIO::BindInterrupt
   182 	(
   183 	TInt     aId,
   184    	TGpioIsr aIsr,
   185    	TAny *   aPtr
   186 	)
   187 	{
   188 	if (aId < 0 || aId > KHwGpioPinMax || aIsr == NULL)
   189 		{
   190 		return KErrArgument;
   191 		}
   192 	if (GpioPins[aId].iIsr != NULL)
   193 		{
   194 		// already bound
   195 		return KErrInUse;
   196 		}
   197 	// record isr and arg bound to this pin
   198 	GpioPins[aId].iIsr = aIsr;
   199 	GpioPins[aId].iPtr = aPtr;
   200 	return KErrNone;
   201 	}
   202 
   203 EXPORT_C TInt GPIO::UnbindInterrupt
   204 	(
   205 	TInt aId
   206 	)
   207 	{
   208 	if (aId < 0 || aId > KHwGpioPinMax)
   209 		{
   210 		return KErrArgument;
   211 		}
   212 	if (GpioPins[aId].iIsr == NULL)
   213 		{
   214 		// nothing bound
   215 		return KErrGeneral;
   216 		}
   217 	// NULL isr bound to this pin
   218 	GpioPins[aId].iIsr = NULL;
   219 	GpioPins[aId].iPtr = NULL;
   220 	return KErrNone;
   221 	}
   222 
   223 EXPORT_C TInt GPIO::EnableInterrupt
   224 	(
   225 	TInt aId
   226 	)
   227 	{
   228 	if (aId < 0 || aId > KHwGpioPinMax)
   229 		{
   230 		return KErrArgument;
   231 		}
   232 	if (GpioPins[aId].iIsr == NULL)
   233 		{
   234 		// nothing bound
   235 		return KErrGeneral;
   236 		}
   237 	// TODO: enable interrupts on this pin
   238 	return KErrNone;
   239 	}
   240 
   241 EXPORT_C TInt GPIO::DisableInterrupt
   242 	(
   243 	TInt aId
   244 	)
   245 	{
   246 	if (aId < 0 || aId > KHwGpioPinMax)
   247 		{
   248 		return KErrArgument;
   249 		}
   250 	if (GpioPins[aId].iIsr == NULL)
   251 		{
   252 		// nothing bound
   253 		return KErrGeneral;
   254 		}
   255 	// TODO: disable interrupts on this pin
   256 	return KErrNone;
   257 	}
   258 
   259 EXPORT_C TInt GPIO::IsInterruptEnabled
   260 	(
   261 	TInt    aId,
   262    	TBool & aEnable
   263 	)
   264 	{
   265 	if (aId < 0 || aId > KHwGpioPinMax)
   266 		{
   267 		return KErrArgument;
   268 		}
   269 	if (GpioPins[aId].iIsr == NULL)
   270 		{
   271 		// nothing bound
   272 		return KErrGeneral;
   273 		}
   274 	// TO DO: are interrupts enabled on this pin ?
   275 	return KErrNone;
   276 	}
   277 
   278 EXPORT_C TInt GPIO::ClearInterrupt
   279 	(
   280 	TInt aId
   281 	)
   282 	{
   283 	if (aId < 0 || aId > KHwGpioPinMax)
   284 		{
   285 		return KErrArgument;
   286 		}
   287 	if (GpioPins[aId].iIsr == NULL)
   288 		{
   289 		// nothing bound
   290 		return KErrGeneral;
   291 		}
   292 	// TO DO: clear pin interrupt status
   293 	return KErrNone;
   294 	}
   295 
   296 EXPORT_C TInt GPIO::GetMaskedInterruptState
   297 	(
   298 	TInt    aId,
   299    	TBool & aActive
   300 	)
   301 	{
   302 	if (aId < 0 || aId > KHwGpioPinMax)
   303 		{
   304 		return KErrArgument;
   305 		}
   306 	// TO DO: set aActive to masked interrupt state
   307 	return KErrNone;
   308 	}
   309 
   310 EXPORT_C TInt GPIO::GetRawInterruptState
   311 	(
   312 	TInt    aId,
   313    	TBool & aActive
   314 	)
   315 	{
   316 	if (aId < 0 || aId > KHwGpioPinMax)
   317 		{
   318 		return KErrArgument;
   319 		}
   320 	// TO DO: set aActive to raw (unmasked) interrupt state
   321 	return KErrNone;
   322 	}
   323 
   324 EXPORT_C TInt GPIO::SetInterruptTrigger
   325 	(
   326 	TInt                  aId,
   327    	TGpioDetectionTrigger aTrigger
   328 	)
   329 	{
   330 	if (aId < 0 || aId > KHwGpioPinMax)
   331 		{
   332 		return KErrArgument;
   333 		}
   334 	// TO DO: set interrupt trigger on this pin
   335 	return KErrNone;
   336 	}
   337 
   338 EXPORT_C TInt GPIO::EnableWakeup
   339 	(
   340 	TInt aId
   341 	)
   342 	{
   343 	if (aId < 0 || aId > KHwGpioPinMax)
   344 		{
   345 		return KErrArgument;
   346 		}
   347 	// TO DO: enable wakeup on this pin
   348 	return KErrNone;
   349 	}
   350 
   351 EXPORT_C TInt GPIO::DisableWakeup
   352 	(
   353 	TInt aId
   354 	)
   355 	{
   356 	if (aId < 0 || aId > KHwGpioPinMax)
   357 		{
   358 		return KErrArgument;
   359 		}
   360 	// TO DO: disable wakeup on this pin
   361 	return KErrNone;
   362 	}
   363 
   364 EXPORT_C TInt GPIO::IsWakeupEnabled
   365 	(
   366 	TInt    aId,
   367    	TBool & aEnable
   368 	)
   369 	{
   370 	if (aId < 0 || aId > KHwGpioPinMax)
   371 		{
   372 		return KErrArgument;
   373 		}
   374 	// TO DO: set aEnable wakeup state for this pin
   375 	return KErrNone;
   376 	}
   377 
   378 EXPORT_C TInt GPIO::SetWakeupTrigger
   379 	(
   380 	TInt                  aId,
   381    	TGpioDetectionTrigger aTrigger
   382 	)
   383 	{
   384 	if (aId < 0 || aId > KHwGpioPinMax)
   385 		{
   386 		return KErrArgument;
   387 		}
   388 	// TO DO: set wakeup trigger on this pin
   389 	return KErrNone;
   390 	}
   391 
   392 EXPORT_C TInt GPIO::SetDebounceTime
   393 	(
   394 	TInt aId,
   395    	TInt aTime
   396 	)
   397 	{
   398 	if (aId < 0 || aId > KHwGpioPinMax)
   399 		{
   400 		return KErrArgument;
   401 		}
   402 	// TO DO: set debounce time for this pin
   403 	// it may be necessary to emulate debouncing ourselves
   404 	return KErrNone;
   405 	}
   406 
   407 EXPORT_C TInt GPIO::GetDebounceTime
   408 	(
   409 	TInt   aId,
   410    	TInt & aTime
   411 	)
   412 	{
   413 	if (aId < 0 || aId > KHwGpioPinMax)
   414 		{
   415 		return KErrArgument;
   416 		}
   417 	// TO DO: get debounce time for this pin
   418 	return KErrNone;
   419 	}
   420 
   421 EXPORT_C TInt GPIO::GetInputState
   422 	(
   423 	TInt         aId,
   424    	TGpioState & aState
   425 	)
   426 	{
   427 	if (aId < 0 || aId > KHwGpioPinMax)
   428 		{
   429 		return KErrArgument;
   430 		}
   431 	// TO DO: read the input state of this pin
   432 	// if debouncing is handled by the driver here
   433 	// is where we will need to work out what the
   434 	// debounced state is
   435 
   436 	return KErrNone;
   437 	}
   438 
   439 EXPORT_C TInt GPIO::SetOutputState
   440 	(
   441 	TInt       aId,
   442    	TGpioState aState
   443 	)
   444 	{
   445 	if (aId < 0 || aId > KHwGpioPinMax)
   446 		{
   447 		return KErrArgument;
   448 		}
   449 	// TO DO: set the output state of this pin
   450 	return KErrNone;
   451 	}
   452 
   453 EXPORT_C TInt GPIO::GetOutputState
   454 	(
   455 	TInt         aId,
   456    	TGpioState & aState
   457 	)
   458 	{
   459 	if (aId < 0 || aId > KHwGpioPinMax)
   460 		{
   461 		return KErrArgument;
   462 		}
   463 	// TO DO: get the output state of this pin
   464 	return KErrNone;
   465 	}
   466 
   467 EXPORT_C TInt GPIO::GetInputState
   468 	(
   469 	TInt                  aId,
   470    	TGpioCallback		* aCb
   471 	)
   472 	{
   473 	if (aId < 0 || aId > KHwGpioPinMax)
   474 		{
   475 		return KErrArgument;
   476 		}
   477 	// TO DO: get the input state of this pin
   478 	return KErrNone;
   479 	}
   480 
   481 EXPORT_C TInt GPIO::SetOutputState
   482 	(
   483 	TInt                  aId,
   484 	TGpioState			  aState,
   485    	TGpioCallback		* aCb
   486 	)
   487 	{
   488 	if (aId < 0 || aId > KHwGpioPinMax)
   489 		{
   490 		return KErrArgument;
   491 		}
   492 	// TO DO: set the ouput state of this pin
   493 	return KErrNone;
   494 	}
   495 
   496 EXPORT_C TInt GPIO::StaticExtension
   497 	(
   498 	TInt	  aId,
   499 	TInt	  aCmd,
   500 	TAny	* aArg1,
   501 	TAny	* aArg2
   502 	)
   503 	{
   504 	if (aId < 0 || aId > KHwGpioPinMax)
   505 		{
   506 		return KErrArgument;
   507 		}
   508 	// TO DO: call the appropriate static extension if supported
   509 	return KErrNotSupported;
   510 	}
   511 
   512 
   513 //
   514 // entry point for GPIO setup
   515 //
   516 DECLARE_STANDARD_EXTENSION()
   517 	{
   518 
   519 	// initialise GPIO pins array (if necessary)
   520 	for (TInt32 i = 0; i <= KHwGpioPinMax; i++)
   521 		{
   522 		GpioPins[i].iIsr = NULL;
   523 		GpioPins[i].iPtr = NULL;
   524 		}
   525 	// bind and enable GPIO Isr
   526 	// NB Interrupt::Bind() now returns a handle (-ve value means an error)
   527 	TInt r = Interrupt::Bind(KIntIdGpio, GpioIsrDispatch, &GpioPins[0]);
   528 	if (r < 0)
   529 		{
   530 		return r;
   531 		}
   532 	// store handle
   533 	GpioInterruptId = r;
   534 	// NB Interrupt::Enable() now expects the handle return from Bind
   535 	r = Interrupt::Enable(r);
   536 	return r;
   537 	}