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