/***************************************************************************
 *
 *  Oxford Semiconductor Proprietary and Confidential Information
 *
 *  Copyright:      Oxford Semiconductor Ltd, 2006
 *
 *  Description:    Definition of the GPIO core I/O control codes
 *                  and structures.
 *
 ***************************************************************************/

#ifndef INC_GpioCoreIoControls_h
#define INC_GpioCoreIoControls_h



/**
 *  I/O control codes.
 */
typedef enum
{
    GET_DESCRIPTION,
    SET_CONFIGURATION,
    GET_CONFIGURATION,
    SET_OUTPUT_VALUES,
    GET_INPUT_VALUES,

    NUMBER_OF_IO_CONTROL_CODES

} GpioIoControlCode;


/**
 *  Possible GPIO IOCTL versions.
 */
typedef enum
{
    GPIO_VERSION_1  = 1

} GpioVersion;


/**
 *  Possible GPIO pin modes.
 */
typedef enum
{
    PIN_MODE_INPUT                  = 0x00,
    PIN_MODE_OUTPUT                 = 0x01,
    PIN_MODE_OPEN_DRAIN             = 0x02,
    PIN_MODE_PWM_OUTPUT             = 0x03,

    PIN_MODE_MASK                   = 0x03

} GpioPinMode;


/**
 *  Possible GPIO pin values.
 */
typedef enum
{
    PIN_VALUE_LOW                   = 0x00,
    PIN_VALUE_HIGH                  = 0x01,

    PIN_VALUE_MASK                  = 0x01

} GpioPinValue;


/**
 *  GPIO interrupt and wake-up modes.
 */
#define IW_MODE_RISING_EDGE         0x00
#define IW_MODE_FALLING_EDGE        0x01
#define IW_MODE_HIGH_LEVEL          0x02
#define IW_MODE_LOW_LEVEL           0x03
#define IW_MODE_ANY_EDGE            0x04
#define IW_MODE_WAKEUP_ENABLED      0x08
#define IW_MODE_INTERRUPT_ENABLED   0x10

typedef enum
{
    INTERRUPT_WAKEUP_DISABLED       = 0x00,

    WAKEUP_RISING_EDGE              = IW_MODE_WAKEUP_ENABLED    | IW_MODE_RISING_EDGE,
    WAKEUP_FALLING_EDGE             = IW_MODE_WAKEUP_ENABLED    | IW_MODE_FALLING_EDGE,
    WAKEUP_HIGH_LEVEL               = IW_MODE_WAKEUP_ENABLED    | IW_MODE_HIGH_LEVEL,
    WAKEUP_LOW_LEVEL                = IW_MODE_WAKEUP_ENABLED    | IW_MODE_LOW_LEVEL,
    WAKEUP_ANY_EDGE                 = IW_MODE_WAKEUP_ENABLED    | IW_MODE_ANY_EDGE,

    INTERRUPT_RISING_EDGE           = IW_MODE_INTERRUPT_ENABLED | IW_MODE_RISING_EDGE,
    INTERRUPT_FALLING_EDGE          = IW_MODE_INTERRUPT_ENABLED | IW_MODE_FALLING_EDGE,
    INTERRUPT_HIGH_LEVEL            = IW_MODE_INTERRUPT_ENABLED | IW_MODE_HIGH_LEVEL,
    INTERRUPT_LOW_LEVEL             = IW_MODE_INTERRUPT_ENABLED | IW_MODE_LOW_LEVEL,
    INTERRUPT_ANY_EDGE              = IW_MODE_INTERRUPT_ENABLED | IW_MODE_ANY_EDGE,

    INTERRUPT_WAKEUP_RISING_EDGE    = IW_MODE_INTERRUPT_ENABLED | IW_MODE_WAKEUP_ENABLED | IW_MODE_RISING_EDGE,
    INTERRUPT_WAKEUP_FALLING_EDGE   = IW_MODE_INTERRUPT_ENABLED | IW_MODE_WAKEUP_ENABLED | IW_MODE_FALLING_EDGE,
    INTERRUPT_WAKEUP_HIGH_LEVEL     = IW_MODE_INTERRUPT_ENABLED | IW_MODE_WAKEUP_ENABLED | IW_MODE_HIGH_LEVEL,
    INTERRUPT_WAKEUP_LOW_LEVEL      = IW_MODE_INTERRUPT_ENABLED | IW_MODE_WAKEUP_ENABLED | IW_MODE_LOW_LEVEL,
    INTERRUPT_WAKEUP_ANY_EDGE       = IW_MODE_INTERRUPT_ENABLED | IW_MODE_WAKEUP_ENABLED | IW_MODE_ANY_EDGE,

    INTERRUPT_WAKEUP_MASK           = 0x1F

} GpioInterruptAndWakeupMode;


/**
 *  Possible GPIO frequency source divider log2 values.
 */
typedef enum
{
    PWM_LOG2_DIVIDER_0,
    PWM_LOG2_DIVIDER_16,

    PWM_LOG2_DIVIDER_MAX            = PWM_LOG2_DIVIDER_16

} GpioPwmLog2Divider;



// FIXME Remove align and pack ?
#include "OsAlign.h"
#include "OsPushPack1.h"


/**
 *  GPIO HW description, i.e. IOCTL version and number of GPIO pins.
 *  GET_DESCRIPTION output parameter.
 */
typedef U08                                 GpioPinNumber;
typedef U32                                 GpioPwmSourceFrequency;
typedef OS_ALIGN(1) struct
{
    U08 /* GpioVersion */                   version;
    GpioPinNumber                           numberOfPins;
    U16                                     unused1;
    GpioPwmSourceFrequency                  pwmFrequency;

} OS_PACK1 GpioDescription;


/**
 *  GET_CONFIGURATION input parameter.
 */
typedef OS_ALIGN(1) struct
{
    GpioPinNumber                           number;

} OS_PACK1 GpioSpecifier;


/**
 *  PWM output high and low timings, prescaler, and frequency source divider.
 */
#define PWM_PERIOD_MASK                     0x1FFF
#define PWM_PRESCALER_MASK                  0x00FF

typedef U16                                 GpioPwmPeriod;
typedef U16                                 GpioPwmPrescaler;
typedef OS_ALIGN(2) struct
{
    GpioPwmPeriod                           low;
    GpioPwmPeriod                           high;
    GpioPwmPrescaler                        prescaler;
    U16 /* GpioPwmLog2Divider */            log2Divider;

} OS_PACK1 GpioPwmTiming;


/**
 *  SET_CONFIGURATION input parameter.
 *  GET_CONFIGURATION output parameter.
 */
typedef OS_ALIGN(4) struct
{
    GpioSpecifier                           specifier;
    U08 /* GpioPinMode */                   pinMode;
    U08 /* GpioInterruptAndWakeupMode */    iwMode;
    U08 /* GpioPinValue */                  pinValue;
    GpioPwmTiming                           pwmTiming;

} OS_PACK1 GpioConfiguration;


/**
 *  SET_OUTPUT_VALUES input parameter.
 */
typedef U32                                 GpioPinMask;
typedef OS_ALIGN(4) struct
{
    GpioPinMask                             outputMask;
    GpioPinMask                             outputValues;

} OS_PACK1 GpioOutputValues;


/**
 *  GET_INPUT_VALUES output parameter.
 */
typedef OS_ALIGN(4) struct
{
    GpioPinMask                             inputValues;
    GpioPinMask                             inputMask;
    GpioPinMask                             outputMask;
    GpioPinMask                             outputDrainMask;
    GpioPinMask                             pwmOutputMask;

} OS_PACK1 GpioInputValues;


#include "OsPopPack.h"



#endif // INC_GpioCoreIoControls_h
