/*
 * Copyright (c) 2015-2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdint.h>
#include <stdbool.h>
#if defined(__IAR_SYSTEMS_ICC__)
#include <intrinsics.h>
#endif

/*
 * By default disable both asserts and log for this module.
 * This must be done before DebugP.h is included.
 */
#ifndef DebugP_ASSERT_ENABLED
#define DebugP_ASSERT_ENABLED 0
#endif
#ifndef DebugP_LOG_ENABLED
#define DebugP_LOG_ENABLED 0
#endif

#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOCC32XX.h>
#include <ti/drivers/dpl/DebugP.h>
#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC32XX.h>

/* driverlib header files */
#include <ti/devices/cc32xx/inc/hw_types.h>
#include <ti/devices/cc32xx/inc/hw_memmap.h>
#include <ti/devices/cc32xx/inc/hw_gpio.h>
#include <ti/devices/cc32xx/inc/hw_ints.h>
#include <ti/devices/cc32xx/driverlib/rom.h>
#include <ti/devices/cc32xx/driverlib/rom_map.h>
#include <ti/devices/cc32xx/driverlib/gpio.h>
#include <ti/devices/cc32xx/driverlib/pin.h>
#include <ti/devices/cc32xx/driverlib/prcm.h>

/*
 * Map GPIO_INT types to corresponding CC32XX interrupt options
 */
static const uint8_t interruptType[] = {
    0,                  /* Undefined interrupt type */
    GPIO_FALLING_EDGE,  /* 1 = Interrupt on falling edge */
    GPIO_RISING_EDGE,   /* 2 = Interrupt on rising edge */
    GPIO_BOTH_EDGES,    /* 3 = Interrupt on both edges */
    GPIO_LOW_LEVEL,     /* 4 = Interrupt on low level */
    GPIO_HIGH_LEVEL     /* 5 = Interrupt on high level */
};

/*
 * Table of port interrupt vector numbers
 * Used by setCallback() to create Hwis.
 * Up to 4 port interrupts must be supported
 */
static const uint8_t portInterruptIds[] = {
    INT_GPIOA0, INT_GPIOA1,
    INT_GPIOA2, INT_GPIOA3
};

/* Table of GPIO input types */
const uint16_t inPinTypes [] = {
    PIN_TYPE_STD,       /* GPIO_CFG_IN_NOPULL */
    PIN_TYPE_STD_PU,    /* GPIO_CFG_IN_PU */
    PIN_TYPE_STD_PD     /* GPIO_CFG_IN_PD */
};

/* Table of GPIO output types */
const uint16_t outPinTypes [] = {
    PIN_TYPE_STD,       /* GPIO_CFG_OUT_STD */
    PIN_TYPE_OD,        /* GPIO_CFG_OUT_OD_NOPULL */
    PIN_TYPE_OD_PU,     /* GPIO_CFG_OUT_OD_PU */
    PIN_TYPE_OD_PD      /* GPIO_CFG_OUT_OD_PD */
};

/* Table of GPIO drive strengths */
const uint16_t outPinStrengths [] = {
    PIN_STRENGTH_2MA,    /* GPIO_CFG_OUT_STR_LOW */
    PIN_STRENGTH_4MA,    /* GPIO_CFG_OUT_STR_MED */
    PIN_STRENGTH_6MA     /* GPIO_CFG_OUT_STR_HIGH */
};

/*
 * Table of port bases address. For use with most driverlib calls.
 * Indexed by GPIO port number (0-3).
 */
static const uint32_t gpioBaseAddresses[] = {
    GPIOA0_BASE, GPIOA1_BASE,
    GPIOA2_BASE, GPIOA3_BASE
};

static const uint32_t powerResources[] = {
    PowerCC32XX_PERIPH_GPIOA0,
    PowerCC32XX_PERIPH_GPIOA1,
    PowerCC32XX_PERIPH_GPIOA2,
    PowerCC32XX_PERIPH_GPIOA3,
};

#define NUM_PORTS            4
#define NUM_PINS_PER_PORT    8
#define PORT_MASK            0x3

/*
 * Extracts the GPIO interrupt type from the pinConfig.  Value to index into the
 * interruptType table.
 */
#define getIntTypeNumber(pinConfig) \
    ((pinConfig & GPIO_CFG_INT_MASK) >> GPIO_CFG_INT_LSB)

/* Returns the GPIO port base address */
#define getPortBase(port) (gpioBaseAddresses[(port) & PORT_MASK])

/* Returns the GPIO port number */
#define getPort(port) (port & PORT_MASK)

/* Returns the GPIO power resource ID */
#define getPowerResource(port) (powerResources[port & PORT_MASK])

/* Returns GPIO number from the pinConfig */
#define getGpioNumber(pinConfig) \
    (((pinConfig->port & PORT_MASK) * 8) + getPinNumber(pinConfig->pin))

/* Uninitialized callbackInfo pinIndex */
#define CALLBACK_INDEX_NOT_CONFIGURED 0xFF

/*
 * Device specific interpretation of the GPIO_PinConfig content
 */
typedef struct PinConfig {
    uint8_t pin;
    uint8_t port;
    uint16_t config;
} PinConfig;

/*
 * User defined pin indexes assigned to a port's 8 pins.
 * Used by port interrupt function to locate callback assigned
 * to a pin.
 */
typedef struct PortCallbackInfo {
    /*
     * the port's 8 corresponding
     * user defined pinId indices
     */
    uint8_t pinIndex[NUM_PINS_PER_PORT];
} PortCallbackInfo;

/*
 * Table of portCallbackInfos.
 * One for each port.
 */
static PortCallbackInfo gpioCallbackInfo[NUM_PORTS];

/*
 * bit mask used to determine if a Hwi has been created/constructed
 * for a port already.
 * up to NUM_PORTS port interrupts must be supported
 */
static uint8_t portHwiCreatedBitMask = 0;

/*
 *  Bit mask used to keep track of which of the GPIO objects in the config
 *  structure have interrupts enabled.  This will be used to restore the
 *  interrupts after coming out of LPDS.
 */
static uint32_t configIntsEnabledMask = 0;

#if DebugP_ASSERT_ENABLED
/*
 * Internal boolean to confirm that GPIO_init() has been called.
 */
static bool initCalled = false;
#endif

/* Notification for going into and waking up from LPDS */
static Power_NotifyObj powerNotifyObj;

extern const GPIOCC32XX_Config GPIOCC32XX_config;

static int powerNotifyFxn(unsigned int eventType, uintptr_t eventArg,
    uintptr_t clientArg);

/*
 *  ======== getPinNumber ========
 *
 *  Internal function to efficiently find the index of the right most set bit.
 */
static inline uint32_t getPinNumber(uint32_t x) {
#if defined(__TI_COMPILER_VERSION__)
    return (uint32_t)(__clz(__rbit(x)) & 0x7);
#elif defined(codered) || defined(__GNUC__) || defined(sourcerygxx)
    return (uint32_t)(__builtin_ctz(x) & 0x7);
#elif defined(__IAR_SYSTEMS_ICC__)
    return (uint32_t)(__CLZ(__RBIT(x)) & 0x7);
#elif defined(rvmdk) || defined(__ARMCC_VERSION)
    return (uint32_t)(__clz(__rbit(x)) & 0x7);
#else
    #error "Unsupported compiler used"
#endif
}

/*
 *  ======== GPIO_clearInt ========
 */
void GPIO_clearInt(uint_least8_t index)
{
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    /* Clear GPIO interrupt flag */
    MAP_GPIOIntClear(getPortBase(config->port), config->pin);

    DebugP_log2("GPIO: port 0x%x, pin 0x%x interrupt flag cleared",
        getPort(config->port), config->pin);
}

/*
 *  ======== GPIO_disableInt ========
 */
void GPIO_disableInt(uint_least8_t index)
{
    uintptr_t  key;
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    /* Make atomic update */
    key = HwiP_disable();

    /* Disable GPIO interrupt */
    MAP_GPIOIntDisable(getPortBase(config->port), config->pin);

    configIntsEnabledMask &= ~(1 << index);

    HwiP_restore(key);

    DebugP_log2("GPIO: port 0x%x, pin 0x%x interrupts disabled",
        getPort(config->port), config->pin);
}

/*
 *  ======== GPIO_enableInt ========
 */
void GPIO_enableInt(uint_least8_t index)
{
    uintptr_t  key;
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    /* Make atomic update */
    key = HwiP_disable();

    /* Enable GPIO interrupt */
    MAP_GPIOIntEnable(getPortBase(config->port), config->pin);

    configIntsEnabledMask |= (1 << index);

    HwiP_restore(key);

    DebugP_log2("GPIO: port 0x%x, pin 0x%x interrupts enabled",
        getPort(config->port), config->pin);
}

/*
 *  ======== GPIO_getConfig ========
 */
void GPIO_getConfig(uint_least8_t index, GPIO_PinConfig *pinConfig)
{
    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    *pinConfig = GPIOCC32XX_config.pinConfigs[index];
}

/*
 *  ======== GPIO_hwiIntFxn ========
 *  Hwi function that processes GPIO interrupts.
 */
void GPIO_hwiIntFxn(uintptr_t portIndex)
{
    unsigned int      bitNum;
    unsigned int      pinIndex;
    uint32_t          pins;
    uint32_t          portBase;
    PortCallbackInfo *portCallbackInfo;

    portCallbackInfo = &gpioCallbackInfo[portIndex];
    portBase = getPortBase(portIndex);

    /* Find out which pins have their interrupt flags set */
    pins = MAP_GPIOIntStatus(portBase, 0xFF) & 0xFF;

    /* clear all the set bits at once */
    MAP_GPIOIntClear(portBase, pins);

    /* Match the interrupt to its corresponding callback function */
    while (pins) {
        /* Gets the lowest order set bit number */
        bitNum = getPinNumber(pins);
        pinIndex = portCallbackInfo->pinIndex[bitNum & 0x7];
        /* only call plugged callbacks */
        if (pinIndex != CALLBACK_INDEX_NOT_CONFIGURED) {
            GPIOCC32XX_config.callbacks[pinIndex](pinIndex);
        }
        pins &= ~(1 << bitNum);
    }
}

/*
 *  ======== GPIO_init ========
 */
void GPIO_init()
{
    unsigned int i, j;

#if DebugP_ASSERT_ENABLED
    initCalled = true;
#endif
    for (i = 0; i < NUM_PORTS; i++) {
        for (j = 0; j < NUM_PINS_PER_PORT; j++) {
            gpioCallbackInfo[i].pinIndex[j] = CALLBACK_INDEX_NOT_CONFIGURED;
        }
    }

    /*
     * Configure pins and create Hwis per static array content
     */
    for (i = 0; i < GPIOCC32XX_config.numberOfPinConfigs; i++) {
        if (!(GPIOCC32XX_config.pinConfigs[i] & GPIO_DO_NOT_CONFIG)) {

            GPIO_setConfig(i, GPIOCC32XX_config.pinConfigs[i]);
        }
        if (i < GPIOCC32XX_config.numberOfCallbacks) {
            if (GPIOCC32XX_config.callbacks[i] != NULL) {
                /* create Hwi as necessary */
                GPIO_setCallback(i, GPIOCC32XX_config.callbacks[i]);
            }
        }
    }

    Power_registerNotify(&powerNotifyObj,
            PowerCC32XX_ENTERING_LPDS | PowerCC32XX_AWAKE_LPDS,
            powerNotifyFxn, (uintptr_t) NULL);
}

/*
 *  ======== GPIO_read ========
 */
uint_fast8_t GPIO_read(uint_least8_t index)
{
    unsigned int value;

    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    value = MAP_GPIOPinRead(getPortBase(config->port), config->pin);

    DebugP_log3("GPIO: port 0x%x, pin 0x%x read 0x%x",
        getPort(config->port), config->pin, value);

    value = (value & config->pin) ? 1 : 0;

    return (value);
}

/*
 *  ======== GPIO_setCallback ========
 */
void GPIO_setCallback(uint_least8_t index, GPIO_CallbackFxn callback)
{
    uint32_t   pinNum;
    uint32_t   portIndex;
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfCallbacks);

    /*
     * plug the pin index into the corresponding
     * port's callbackInfo pinIndex entry
     */
    pinNum = getPinNumber(config->pin);
    portIndex = config->port & PORT_MASK;

    if (callback == NULL) {
        gpioCallbackInfo[portIndex].pinIndex[pinNum] =
            CALLBACK_INDEX_NOT_CONFIGURED;
    }
    else {
        gpioCallbackInfo[portIndex].pinIndex[pinNum] = index;
    }

    /*
     * Only update callBackFunctions entry if different.
     * This allows the callBackFunctions array to be in flash for static systems.
     */
    if (GPIOCC32XX_config.callbacks[index] != callback) {
        GPIOCC32XX_config.callbacks[index] = callback;
    }
}

/*
 *  ======== GPIO_setConfig ========
 */
int_fast16_t GPIO_setConfig(uint_least8_t index, GPIO_PinConfig pinConfig)
{
    uintptr_t      key;
    uint32_t       pin;
    uint32_t       pad;
    uint32_t       portBase;
    uint32_t       portIndex;
    uint32_t       portBitMask;
    uint16_t       direction;
    uint16_t       strength;
    uint16_t       pinType;
    HwiP_Handle    hwiHandle;
    HwiP_Params    hwiParams;
    GPIO_PinConfig gpioPinConfig;
    PinConfig     *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);

    if (pinConfig & GPIO_DO_NOT_CONFIG) {
        return (GPIO_STATUS_SUCCESS);
    }

    portBase = getPortBase(config->port);
    pin = config->pin;
    pad = PinFromPadGet((unsigned long)getGpioNumber(config));

    /* Make atomic update */
    key = HwiP_disable();

    /* set the pad's pinType to GPIO */
    MAP_PinModeSet(pad, PIN_MODE_0);

    /* enable clocks for the GPIO port */
    Power_setDependency(getPowerResource(config->port));

    HwiP_restore(key);

    if ((pinConfig & GPIO_CFG_IN_INT_ONLY) == 0) {
        if (pinConfig & GPIO_CFG_INPUT) {
            /* configure input */
            direction = GPIO_DIR_MODE_IN;
            strength = PIN_STRENGTH_2MA;
            pinType = inPinTypes[(pinConfig & GPIO_CFG_IN_TYPE_MASK) >>
                GPIO_CFG_IN_TYPE_LSB];
        }
        else {
            /* configure output */
            direction = GPIO_DIR_MODE_OUT;
            strength =
                outPinStrengths[(pinConfig & GPIO_CFG_OUT_STRENGTH_MASK) >>
                GPIO_CFG_OUT_STRENGTH_LSB];
            pinType = outPinTypes[(pinConfig & GPIO_CFG_OUT_TYPE_MASK) >>
                GPIO_CFG_OUT_TYPE_LSB];
        }

        key = HwiP_disable();

        /* Configure the GPIO pin */
        MAP_GPIODirModeSet(portBase, pin, direction);
        MAP_PinConfigSet(pad, strength, pinType);

        /* Set output value */
        if (direction == GPIO_DIR_MODE_OUT) {
            MAP_GPIOPinWrite(portBase, pin,
                ((pinConfig & GPIO_CFG_OUT_HIGH) ? 0xFF : 0));
        }

        /*
         *  Update pinConfig with the latest GPIO configuration and
         *  clear the GPIO_DO_NOT_CONFIG bit if it was set.
         */
        gpioPinConfig = GPIOCC32XX_config.pinConfigs[index];
        gpioPinConfig &= ~(GPIO_CFG_IO_MASK | GPIO_DO_NOT_CONFIG);
        gpioPinConfig |= (pinConfig & GPIO_CFG_IO_MASK);
        GPIOCC32XX_config.pinConfigs[index] = gpioPinConfig;

        HwiP_restore(key);
    }

    /* Set type of interrupt and then clear it */
    if (pinConfig & GPIO_CFG_INT_MASK) {
        portIndex = config->port & PORT_MASK;
        portBitMask = 1 << portIndex;

        /* if Hwi has not already been created, do so */
        if ((portHwiCreatedBitMask & portBitMask) == 0) {
            HwiP_Params_init(&hwiParams);
            hwiParams.arg = (uintptr_t) portIndex;
            hwiParams.priority = GPIOCC32XX_config.intPriority;
            hwiHandle = HwiP_create(portInterruptIds[portIndex], GPIO_hwiIntFxn,
                &hwiParams);
            if (hwiHandle == NULL) {
                /* Error creating Hwi */
                DebugP_log1("GPIO: Error constructing Hwi for GPIO Port %d",
                    getPort(config->port));
                return (GPIO_STATUS_ERROR);
            }
        }

        key = HwiP_disable();

        /* Mark the Hwi as created */
        portHwiCreatedBitMask |= portBitMask;

        MAP_GPIOIntTypeSet(portBase, pin,
            interruptType[getIntTypeNumber(pinConfig)]);
        MAP_GPIOIntClear(portBase, pin);

        /*
         *  Update pinConfig with the latest interrupt configuration and
         *  clear the GPIO_DO_NOT_CONFIG bit if it was set.
         */
        gpioPinConfig = GPIOCC32XX_config.pinConfigs[index];
        gpioPinConfig &= ~(GPIO_CFG_INT_MASK | GPIO_DO_NOT_CONFIG);
        gpioPinConfig |= (pinConfig & GPIO_CFG_INT_MASK);
        GPIOCC32XX_config.pinConfigs[index] = gpioPinConfig;

        HwiP_restore(key);
    }

    return (GPIO_STATUS_SUCCESS);
}

/*
 *  ======== GPIO_toggle ========
 */
void GPIO_toggle(uint_least8_t index)
{
    uintptr_t  key;
    uint32_t   value;
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);
    DebugP_assert((GPIOCC32XX_config.pinConfigs[index] & GPIO_CFG_INPUT) ==
        GPIO_CFG_OUTPUT);

    /* Make atomic update */
    key = HwiP_disable();

    value = MAP_GPIOPinRead(getPortBase(config->port), config->pin);
    value ^= config->pin;
    MAP_GPIOPinWrite(getPortBase(config->port), config->pin, value);

    /* Update config table entry with value written */
    GPIOCC32XX_config.pinConfigs[index] ^= GPIO_CFG_OUT_HIGH;

    HwiP_restore(key);

    DebugP_log2("GPIO: port 0x%x, pin 0x%x toggled",
        getPort(config->port), config->pin);
}

/*
 *  ======== GPIO_write ========
 */
void GPIO_write(uint_least8_t index, unsigned int value)
{
    uintptr_t  key;
    uint32_t   output;
    PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];

    DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);
    DebugP_assert((GPIOCC32XX_config.pinConfigs[index] & GPIO_CFG_INPUT) ==
        GPIO_CFG_OUTPUT);

    key = HwiP_disable();

    /* Clear output from pinConfig */
    GPIOCC32XX_config.pinConfigs[index] &= ~GPIO_CFG_OUT_HIGH;

    if (value) {
        output = config->pin;

        /* Set the pinConfig output bit to high */
        GPIOCC32XX_config.pinConfigs[index] |= GPIO_CFG_OUT_HIGH;
    }
    else {
        output = value;
    }

    MAP_GPIOPinWrite(getPortBase(config->port), config->pin, output);

    HwiP_restore(key);

    DebugP_log3("GPIO: port 0x%x, pin 0x%x wrote 0x%x",
       getPort(config->port), config->pin, value);
}

/*
 *  ======== powerNotifyFxn ========
 */
static int powerNotifyFxn(unsigned int eventType, uintptr_t eventArg,
    uintptr_t clientArg)
{
    unsigned int   i;
    uint32_t       ulRegVal;
    GPIO_PinConfig config;
    uint32_t       output;
    uint32_t       pad;
    PinConfig     *pinConfig;
    PowerCC32XX_ParkState state;

    if (eventType == PowerCC32XX_AWAKE_LPDS) {
        /* Take GPIO semaphore */
        ulRegVal = HWREG(0x400F703C);
        ulRegVal = (ulRegVal & ~0x3FF) | 0x155;
        HWREG(0x400F703C) = ulRegVal;

        for (i = 0; i < GPIOCC32XX_config.numberOfPinConfigs; i++) {
            if (!(GPIOCC32XX_config.pinConfigs[i] & GPIO_DO_NOT_CONFIG)) {
                config = GPIOCC32XX_config.pinConfigs[i];

                GPIO_setConfig(i, config);

                if (configIntsEnabledMask & (1 << i)) {
                    GPIO_enableInt(i);
                }
            }
        }
    }
    else {
        /* Entering LPDS */
        /*
         *  For pins configured as GPIO output, if the GPIOCC32XX_USE_STATIC
         *  configuration flag is *not* set, get the current pin state, and
         *  then call to the Power manager to define the state to be held
         *  during LPDS.
         *  If GPIOCC32XX_USE_STATIC *is* defined, do nothing, and the pin
         *  will be parked in the state statically defined in
         *  PowerCC32XX_config.pinParkDefs[] in the board file.
         */
        for (i = 0; i < GPIOCC32XX_config.numberOfPinConfigs; i++) {
            if (GPIOCC32XX_config.pinConfigs[i] & GPIO_DO_NOT_CONFIG) {
                continue;
            }

            config =  GPIOCC32XX_config.pinConfigs[i];

            /* if OUTPUT, and GPIOCC32XX_USE_STATIC flag is not set */
            if ((!(config & GPIO_CFG_INPUT)) &&
                (!(config & GPIOCC32XX_USE_STATIC))) {

                pinConfig = (PinConfig *) &GPIOCC32XX_config.pinConfigs[i];

                /* determine state to be held */
                pad = PinFromPadGet((unsigned long)getGpioNumber(pinConfig));
                output = config & GPIO_CFG_OUT_HIGH;
                state = (PowerCC32XX_ParkState) ((output) ? 1 : 0);

                /* set the new park state */
                PowerCC32XX_setParkState((PowerCC32XX_Pin)pad, state);
            }
        }
    }

    return (Power_NOTIFYDONE);
}
