/** \file vp880_fxs_control.c
 * vp880_fxs_control.c
 *
 *  This file contains the control functions for the FXS lines of the VP880
 * device.
 *
 * Copyright (c) 2011, Microsemi
 *
 * $Revision: 1.1.2.1.8.3 $
 * $LastChangedDate: 2010-03-23 14:01:46 -0500 (Tue, 23 Mar 2010) $
 */

#include "../includes/vp_api_cfg.h"

#if defined (VP_CC_880_SERIES) && defined (VP880_FXS_SUPPORT)

/* INCLUDES */
#include "../../arch/uvb/vp_api_types.h"
#include "../../arch/uvb/vp_hal.h"
#include "../includes/vp_api_int.h"
#include "../includes/vp880_api.h"
#include "../vp880_api/vp880_api_int.h"
#include "../../arch/uvb/sys_service.h"

/**< Functions called by Set Line State to abstract device states used for ABS
 * and non ABS devices (if they are different). Set line state then operates
 * on device state only (abstracted from API-II line state).
 */
static void
Vp880ApplyInternalTestTerm(
    VpLineCtxType *pLineCtx);

static void
Vp880RemoveInternalTestTerm(
    VpLineCtxType *pLineCtx);

/**
 * Vp880ProcessFxsLine()
 *  This function should only be called by Vp880ApiTick on FXS lines. It
 * performs all line processing for operations that are Tick based
 *
 * Preconditions:
 *  Conditions defined by purpose of Api Tick.
 *
 * Postconditions:
 *  The Api variables and events (as appropriate) for the line passed have been
 * updated.
 */
VpStatusType
Vp880ProcessFxsLine(
    Vp880DeviceObjectType *pDevObj,
    VpLineCtxType *pLineCtx)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    uint8 channelId = pLineObj->channelId;
    bool dpStatus[2] = {FALSE, FALSE};
    VpOptionEventMaskType lineEvents1;
    VpOptionEventMaskType lineEvents2;
    VpDialPulseDetectStatesType beforeState, afterState;
    uint8 hookStatus = 0, i, validSamples;
    uint8 hookIncrement;
    bool dp2Valid;

#ifdef VP880_INCLUDE_TESTLINE_CODE
    /* Skip processing during line test */
    if (Vp880IsChnlUndrTst(pDevObj, channelId) == TRUE) {
        return VP_STATUS_SUCCESS;
    }
#endif

    lineEvents1.signaling = 0;
    lineEvents2.signaling = 0;

    /* If the secondary pulse params are all 0 (default), mark them as invalid
     * so that they will not be used. */
    if (pDevObj->pulseSpecs2.breakMin == 0 &&
        pDevObj->pulseSpecs2.breakMax == 0 &&
        pDevObj->pulseSpecs2.makeMin == 0 &&
        pDevObj->pulseSpecs2.makeMax == 0 &&
#ifdef EXTENDED_FLASH_HOOK
        pDevObj->pulseSpecs2.onHookMin == 0 &&
#endif
        pDevObj->pulseSpecs2.interDigitMin == 0 &&
        pDevObj->pulseSpecs2.flashMin == 0 &&
        pDevObj->pulseSpecs2.flashMax == 0) {

        dp2Valid = FALSE;

    } else {
        dp2Valid = TRUE;
    }

    /*
     * If the line is configured for Dial Pulse Detection, run the Dial Pulse
     * detection code. Dial Pulse detection code will generate the appropriate
     * events
     */
    if((pLineObj->pulseMode == VP_OPTION_PULSE_DECODE_ON) &&
       (!(pLineObj->lineState.condition & VP_CSLAC_LINE_LEAK_TEST))) {
        /*
         * Based on the following (vp880_api_int.h):
         *
         *  #define VP880_CC_500HZ_RATE     0x40
         *  #define VP880_CC_1KHZ_RATE      0x30
         *  #define VP880_CC_2KHZ_RATE      0x20
         *  #define VP880_CC_4KHZ_RATE      0x10
         *  #define VP880_CC_8KHZ_RATE      0x00
         */

        /*
         * Get the incremental steps sizes in 125us increments used to apply to the on/off-hook
         * times below, which is also the same scale as the Dial Pulse Detection Parameters.
         */
        uint8 shiftAmt = ((pDevObj->txBufferDataRate >> 4) & 0x7);
        hookIncrement = (1 << shiftAmt);

        validSamples = ((pDevObj->txBuffer[VP880_TX_BUF_HOOK_MSB_INDEX]
            & VP880_TX_BUF_LEN_MASK) >> 4);

        if (validSamples == 7) {
            validSamples = 6;
        }

        if (channelId == 0) {
            hookStatus = pDevObj->txBuffer[VP880_TX_BUF_HOOK_LSB_INDEX]
                & VP880_TX_BUF_HOOK_CHAN1_MASK;
        } else {
            hookStatus = (pDevObj->txBuffer[VP880_TX_BUF_HOOK_MSB_INDEX]
                & VP880_TX_BUF_HOOK_MSB_MASK) << 2;
            hookStatus |= ((pDevObj->txBuffer[VP880_TX_BUF_HOOK_LSB_INDEX]
                & VP880_TX_BUF_HOOK_CHAN2_MASK) >> 6);
        }
        /*
         * If the line is currently in Low Power Mode, the meaning applied to the hook detector is
         * inverted from it's normal meaning. A "high" signal level into the hook detector, which
         * normally measures current, will cause the hook bit to be set = '1'. The SW has to
         * understand that the hook detector is being fed line voltage when in LPM and interpret
         * that to mean the customer phone is on-hook. In normal detection mode where the
         * hook detector is being fed current, a "high" signal level means high current = phone is
         * off-hook.
         */
        if (pLineObj->status & VP880_LOW_POWER_EN) {
            hookStatus = ~hookStatus;
        }

        beforeState = pLineObj->dpStruct.state;

        /*
         * This flag is set when the Test Buffer (more specifically, the Hook-Bit buffer) has been
         * read this tick. It could happen when a hook interrupt occurs or not (i.e., there are a
         * few reasons for reading the test buffer). It should ONLY be set on silicon > VC, but it
         * isn't too much effort to check for both Hook-Bit Buffer read AND > VC silicon before
         * processing the data.
         */
        if ((pDevObj->state & VP_DEV_TEST_BUFFER_READ) &&
            (pDevObj->staticInfo.rcnPcn[VP880_RCN_LOCATION] > VP880_REV_VC)) {
            /*
             * Loop Open and Loop Close times are only at the accuracy of the tickrate now. We
             * want to improve that by looking for the point the hook status changed in the hook-bit
             * buffer and adjust based on the hook bit buffer sample rate (i.e., hook increment set
             * above).
             */
            VP_HOOK(VpLineCtxType, pLineCtx,
                    ("CH%d Validsamples %d, buffer %02X %02X %d%d%d%d%d%d  at time %d",
                     channelId,
                     ((pDevObj->txBuffer[VP880_TX_BUF_HOOK_MSB_INDEX] & VP880_TX_BUF_LEN_MASK) >> 4),
                     pDevObj->txBuffer[0], pDevObj->txBuffer[1],
                     (hookStatus & 0x20) == 0x20,
                     (hookStatus & 0x10) == 0x10,
                     (hookStatus & 0x08) == 0x08,
                     (hookStatus & 0x04) == 0x04,
                     (hookStatus & 0x02) == 0x02,
                     (hookStatus & 0x01) == 0x01,
                     pDevObj->timeStamp));

            for (i = 1; i < (1 << validSamples); i <<= 1) {
                if (beforeState == VP_DP_DETECT_STATE_LOOP_CLOSE) {
                    if (!(hookStatus & i)) {
                        VP_HOOK(VpLineCtxType, pLineCtx,
                                ("CH%d - Loop Close Time (%d) at time (%d) Hook Increment (%d)",
                                 channelId, pLineObj->dpStruct.lc_time, pDevObj->timeStamp,
                                 hookIncrement));

                        if (pLineObj->dpStruct.lc_time > hookIncrement) {
                            pLineObj->dpStruct.lc_time -= hookIncrement;
                        }
                        if (pLineObj->dpStruct2.lc_time > hookIncrement) {
                            pLineObj->dpStruct2.lc_time -= hookIncrement;
                        }
                    } else {
                        break;
                    }
                } else if (beforeState == VP_DP_DETECT_STATE_LOOP_OPEN) {
                    if (hookStatus & i) {
                        VP_HOOK(VpLineCtxType, pLineCtx,
                                ("CH%d - Loop Open Time (%d) at time (%d) Hook Increment (%d)",
                                 channelId, pLineObj->dpStruct.lo_time, pDevObj->timeStamp,
                                 hookIncrement));

                        if (pLineObj->dpStruct.lo_time > hookIncrement) {
                            pLineObj->dpStruct.lo_time -= hookIncrement;
                        }
                        if (pLineObj->dpStruct2.lo_time > hookIncrement) {
                            pLineObj->dpStruct2.lo_time -= hookIncrement;
                        }
                    } else {
                        break;
                    }
                }
            }

            VP_HOOK(VpLineCtxType, pLineCtx,
                    ("CH%d Fine Measurement Loop Open Time (%d) Loop Close Time (%d) at time %d",
                     channelId, pLineObj->dpStruct.lo_time, pLineObj->dpStruct.lc_time,
                     pDevObj->timeStamp));
        }

        if ((!(pDevObj->stateInt & VP880_IS_ABS)) &&
            (pDevObj->swParamsCache[VP880_REGULATOR_TRACK_INDEX] & VP880_REGULATOR_FIXED_RING)) {
            /* Compensate for slow onhook detection with Fixed Mode Tracking Designs */
            if (beforeState == VP_DP_DETECT_STATE_LOOP_CLOSE && !(pLineObj->dpStruct.hookSt)) {
                if (pLineObj->dpStruct.lc_time > VP880_PULSE_DETECT_ADJUSTMENT_LONG) {
                    pLineObj->dpStruct.lc_time -= VP880_PULSE_DETECT_ADJUSTMENT_LONG;
                    VP_HOOK(VpLineCtxType, pLineCtx,
                            ("CH%d Long Compensation to Loop Close Time (%d) at time (%d)",
                             channelId, pLineObj->dpStruct.lc_time, pDevObj->timeStamp));
                }
            }
            if (beforeState == VP_DP_DETECT_STATE_LOOP_CLOSE && !(pLineObj->dpStruct2.hookSt)) {
                if (pLineObj->dpStruct2.lc_time > VP880_PULSE_DETECT_ADJUSTMENT_LONG) {
                    pLineObj->dpStruct2.lc_time -= VP880_PULSE_DETECT_ADJUSTMENT_LONG;
                }
            }
        } else {
            /* Compensate just for the silicon */
            if (beforeState == VP_DP_DETECT_STATE_LOOP_CLOSE && !(pLineObj->dpStruct.hookSt)) {
                if (pLineObj->dpStruct.lc_time > VP880_PULSE_DETECT_ADJUSTMENT_SHORT) {
                    pLineObj->dpStruct.lc_time -= VP880_PULSE_DETECT_ADJUSTMENT_SHORT;
                    VP_HOOK(VpLineCtxType, pLineCtx,
                            ("CH%d Short Compensation to Loop Close Time (%d) at time (%d)",
                             channelId, pLineObj->dpStruct.lc_time, pDevObj->timeStamp));
                }
            }
            if (beforeState == VP_DP_DETECT_STATE_LOOP_CLOSE && !(pLineObj->dpStruct2.hookSt)) {
                if (pLineObj->dpStruct2.lc_time > VP880_PULSE_DETECT_ADJUSTMENT_SHORT) {
                    pLineObj->dpStruct2.lc_time -= VP880_PULSE_DETECT_ADJUSTMENT_SHORT;
                }
            }
        }

        dpStatus[0] = VpUpdateDP(pDevObj->devProfileData.tickRate,
            &pDevObj->pulseSpecs, &pLineObj->dpStruct, &lineEvents1);
        if (dp2Valid == TRUE) {
            dpStatus[1] = VpUpdateDP(pDevObj->devProfileData.tickRate,
                &pDevObj->pulseSpecs2, &pLineObj->dpStruct2, &lineEvents2);
        }
        afterState = pLineObj->dpStruct.state;
        /* Update the loop open and close times according to the hook change
         * within a tick */

        /* If the state changed, adjust the hook timings */
        if (beforeState != afterState) {
            if (pDevObj->state & VP_DEV_TEST_BUFFER_READ) {
                for (i = 1; i < (1 << validSamples); i <<= 1) {
                    if (afterState == VP_DP_DETECT_STATE_LOOP_CLOSE) {
                        if (hookStatus & i) {
                            pLineObj->dpStruct.lc_time += hookIncrement;
                            pLineObj->dpStruct2.lc_time += hookIncrement;
                        } else {
                            break;
                        }
                    } else if (afterState == VP_DP_DETECT_STATE_LOOP_OPEN) {
                        if (!(hookStatus & i)) {
                            pLineObj->dpStruct.lo_time += hookIncrement;
                            pLineObj->dpStruct2.lo_time += hookIncrement;
                        } else {
                            break;
                        }
                    }
                }
            }
            if (afterState == VP_DP_DETECT_STATE_LOOP_OPEN) {
                if ((!(pDevObj->stateInt & VP880_IS_ABS)) &&
                    (pDevObj->swParamsCache[VP880_REGULATOR_TRACK_INDEX] & VP880_REGULATOR_FIXED_RING)) {
                    /* Compensate for slow onhook detection with Fixed Mode Tracking Designs */
                    pLineObj->dpStruct.lo_time += VP880_PULSE_DETECT_ADJUSTMENT_LONG;
                    pLineObj->dpStruct2.lo_time += VP880_PULSE_DETECT_ADJUSTMENT_LONG;
                } else {
                    /* Compensate for silicon only */
                    pLineObj->dpStruct.lo_time += VP880_PULSE_DETECT_ADJUSTMENT_SHORT;
                    pLineObj->dpStruct2.lo_time += VP880_PULSE_DETECT_ADJUSTMENT_SHORT;
                }
            }
        }

        /*
         * The state machines will not necessarily complete at the same time, so
         * keep track of each and when both are done, report a passing digit if
         * one exists, or invalid if no criteria was met.
         */
        if (dpStatus[0] == TRUE) {
            pLineObj->signaling1 = lineEvents1.signaling;
            pLineObj->lineEventHandle = pDevObj->timeStamp;

            if (!(pLineObj->lineEvents.signaling & VP_LINE_EVID_BREAK_MAX)) {
                pLineObj->status |= VP880_DP_SET1_DONE;
            }
        }

        if (dpStatus[1] == TRUE && dp2Valid == TRUE) {
            pLineObj->signaling2 = lineEvents2.signaling;
            pLineObj->lineEventHandle = pDevObj->timeStamp;

            if (!(pLineObj->lineEvents.signaling & VP_LINE_EVID_BREAK_MAX)) {
                pLineObj->status |= VP880_DP_SET2_DONE;
            }
        }

        /* Report events if:
         *  Both DP sets are done, OR
         *  Set 1 is done and set 2 is invalid */
        if ((pLineObj->status & VP880_DP_SET1_DONE) &&
            ((pLineObj->status & VP880_DP_SET2_DONE) ||
             dp2Valid == FALSE))
        {
            /* Use the results of DP set 1 if it detected a valid digit, or
             * if DP set 2 detected an invalid digit, or if set 2 is disabled */
            if (pLineObj->dpStruct.digits != -1 ||
                pLineObj->dpStruct2.digits == -1 ||
                dp2Valid == FALSE)
            {
                pLineObj->signalingData = pLineObj->dpStruct.digits;
                pLineObj->lineEvents.signaling |= pLineObj->signaling1;
                pLineObj->lineEventHandle = VP_DP_PARAM1;
            } else {
                pLineObj->signalingData = pLineObj->dpStruct2.digits;
                pLineObj->lineEvents.signaling |= pLineObj->signaling2;
                pLineObj->lineEventHandle = VP_DP_PARAM2;
            }

            if (pLineObj->signalingData == 0) {
                pLineObj->signalingData = pLineObj->lineEventHandle;
                pLineObj->lineEventHandle = pDevObj->timeStamp;
            }

            pLineObj->status &= ~(VP880_DP_SET1_DONE | VP880_DP_SET2_DONE);
            pLineObj->signaling1 = 0;
            pLineObj->signaling2 = 0;
        }
    }

#ifdef VP_CSLAC_SEQ_EN
    /*
     * If Caller ID sequencer is in progress, update unless it's in a state of
     * suspension. If suspended, re-enable if device is in underrun (no more
     * data to transmit).
     */
    if ((pLineObj->callerId.status & VP_CID_IN_PROGRESS)
     || (pLineObj->suspendCid == TRUE)) {
        VpDeviceIdType deviceId = pDevObj->deviceId;
        uint8 ecVal = pLineObj->ecVal;

        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880ProcessFxsLine()+"));

        /* First read of the CID State Machine this tick. */
        VpMpiCmdWrapper(deviceId, ecVal, VP880_CID_PARAM_RD,
            VP880_CID_PARAM_LEN, pLineObj->tickBeginState);
        pLineObj->delayConsumed = FALSE;

        if (pLineObj->suspendCid == TRUE) {
            /*
             * Check to see if the Device Buffer is empty. If it is, continue
             * with CID.
             */
            uint8 cidState = (pLineObj->tickBeginState[0] & VP880_CID_STATE_MASK);

            if ((cidState == VP880_CID_STATE_URUN)
             || (cidState == VP880_CID_STATE_IDLE)) {
                uint8 cidParam = pLineObj->tickBeginState[0];

                pLineObj->suspendCid = FALSE;
                cidParam &= ~(VP880_CID_FRAME_BITS);
                cidParam |= VP880_CID_DIS;

                Vp880MuteChannel(pLineCtx, FALSE);
                if (cidParam != pLineObj->tickBeginState[0]) {
                    pLineObj->tickBeginState[0] = cidParam;
                    VP_CID(VpLineCtxType, pLineCtx,
                        ("Stopping FSK Generator with 0x%02X to CID Params at time %d",
                        pLineObj->tickBeginState[0], pDevObj->timeStamp));
                    VpMpiCmdWrapper(deviceId, ecVal, VP880_CID_PARAM_WRT,
                        VP880_CID_PARAM_LEN, pLineObj->tickBeginState);
                    pLineObj->callerId.status &= ~VP_CID_FSK_ACTIVE;
                }
            }
        }

        if (pLineObj->callerId.status & VP_CID_IN_PROGRESS) {
            VpCidSeq(pLineCtx);
        }
        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880ProcessFxsLine()-"));
    }
#endif
    return VP_STATUS_SUCCESS;
}

/**
 * Vp880SetRelayState()
 *  This function controls the state of controlled relays for the VP880 device.
 *
 * Preconditions:
 *  Device/Line context should be created and initialized. For applicable
 * devices bootload should be performed before calling the function.
 *
 * Postconditions:
 *  The indicated relay state is set for the given line.
 */
VpStatusType
Vp880SetRelayState(
    VpLineCtxType *pLineCtx,
    VpRelayControlType rState)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    uint8 ecVal = pLineObj->ecVal;
    VpTermType termType = pLineObj->termType;

    VpDevCtxType *pDevCtx = pLineCtx->pDevCtx;
    Vp880DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    uint8 pcn = pDevObj->staticInfo.rcnPcn[VP880_PCN_LOCATION];
    uint8 revCode = pDevObj->staticInfo.rcnPcn[VP880_RCN_LOCATION];

    uint8 ioDirection[VP880_IODIR_REG_LEN];
    uint8 ioData[VP880_IODATA_REG_LEN];

    uint8 mpiBuffer[3 + VP880_IODIR_REG_LEN + VP880_IODATA_REG_LEN + VP880_ICR1_LEN];
    uint8 mpiIndex = 0;

    /*
     * In case this function fails, make sure the line object is unchanged by
     * pre-saving it's current value. First step prior to 100% verifiying if
     * this function will be success is to pre-clear the relay control bits.
     */
    uint8 preIcr1Values = pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION];

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState+"));

    /* Proceed if device state is either in progress or complete */
    if (pDevObj->state & (VP_DEV_INIT_CMP | VP_DEV_INIT_IN_PROGRESS)) {
    } else {
        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
        return VP_STATUS_DEV_NOT_INITIALIZED;
    }

    /*
     * Do not proceed if the device calibration is in progress. This could
     * damage the device.
     */
    if (pDevObj->state & VP_DEV_IN_CAL) {
        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
        return VP_STATUS_DEV_NOT_INITIALIZED;
    }

    /*
     * Handle the VP_RELAY_BRIDGED_TEST case for devices that do not have a
     * physical test load.  Use the internal test termination algorithm instead.
     * If the VP880_ALWAYS_USE_INTERNAL_TEST_TERMINATION option is defined in
     * vp_api_cfg.h the HAS_TEST_LOAD_SWITCH flag will always be cleared at
     * initialization so that this method will always be used.  The internal
     * test termination is only supported for revisions newer than VC.
     */
    if (rState == VP_RELAY_BRIDGED_TEST &&
        !(pDevObj->stateInt & VP880_HAS_TEST_LOAD_SWITCH) &&
        revCode > VP880_REV_VC) {
        Vp880ApplyInternalTestTerm(pLineCtx);

        pLineObj->relayState = VP_RELAY_BRIDGED_TEST;

        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
        return VP_STATUS_SUCCESS;
    }

    /* If the internal test termination is currently applied and we're going
     * to a state other than BRIDGED_TEST, restore the internal settings */
    if (pLineObj->internalTestTermApplied == TRUE &&
        rState != VP_RELAY_BRIDGED_TEST) {
        Vp880RemoveInternalTestTerm(pLineCtx);
    }

    /* Read registers that may have partial modifications */
    VpMpiCmdWrapper(deviceId, ecVal, VP880_IODIR_REG_RD, VP880_IODIR_REG_LEN,
        ioDirection);

    VpMpiCmdWrapper(deviceId, ecVal, VP880_IODATA_REG_RD, VP880_IODATA_REG_LEN,
        ioData);

    /* Always set the value for Test Load Control. */
    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION-1] |=
        VP880_ICR1_TEST_LOAD_MASK;

    /* Preclear test load bits */
    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION]
        &= ~(VP880_ICR1_TEST_LOAD_MASK);

    switch (pLineObj->termType) {
        case VP_TERM_FXS_GENERIC:
        case VP_TERM_FXS_LOW_PWR:
            switch (rState) {
                case VP_RELAY_BRIDGED_TEST:
                    if (!(pDevObj->stateInt & VP880_HAS_TEST_LOAD_SWITCH)) {

                        /* Restore values prior to caling this function. */
                        pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION] = preIcr1Values;

                        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
                        return VP_STATUS_INVALID_ARG;
                    }

                    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION]
                        |= VP880_ICR1_TEST_LOAD_METALLIC;

                    /* Test Load bits pre-cleared. Can pick up at Normal */

                case VP_RELAY_NORMAL:
                    break;

                default:
                    /* Restore values prior to caling this function. */
                    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION] = preIcr1Values;

                    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                    VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
                    return VP_STATUS_INVALID_ARG;
            }
            break;

        case VP_TERM_FXS_ISOLATE:
        case VP_TERM_FXS_ISOLATE_LP:
        case VP_TERM_FXS_SPLITTER:
        case VP_TERM_FXS_SPLITTER_LP:
            ioDirection[0] &= ~VP880_IODIR_IO1_MASK;
            ioData[0] &= ~(VP880_IODATA_IO1);

            switch (rState) {
                case VP_RELAY_BRIDGED_TEST:
                    if (!(pDevObj->stateInt & VP880_HAS_TEST_LOAD_SWITCH)) {
                        /* Restore values prior to caling this function. */
                        pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION] = preIcr1Values;

                        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                        VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
                        return VP_STATUS_INVALID_ARG;
                    }

                    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION]
                        |= VP880_ICR1_TEST_LOAD_METALLIC;

                    /* Test Load bits pre-cleared. Can pick up at Normal */

                case VP_RELAY_NORMAL:
                    if (revCode <= VP880_REV_VC) {
                        ioDirection[0] |= VP880_IODIR_IO1_OPEN_DRAIN;

                        if ((termType == VP_TERM_FXS_ISOLATE) ||
                            (termType == VP_TERM_FXS_ISOLATE_LP)) {
                            /*
                             * Dir = open drain, Set Data = 0
                             * This causes the output to go high.
                             */
                            ioData[0] &= ~VP880_IODATA_IO1;
                        } else {
                            /*
                             * Dir = open drain, Set Data = 1
                             * This causes the output to go low.
                             */
                            ioData[0] |= VP880_IODATA_IO1;
                        }
                    } else {
                        /*
                         * Devices VP880_DEV_PCN_88536 and VP880_DEV_PCN_88264
                         * are affected here because the VP-API-II forces the
                         * revision code to >= JA
                         */
                        if ((termType == VP_TERM_FXS_ISOLATE) ||
                            (termType == VP_TERM_FXS_ISOLATE_LP)) {
                            /*
                             * Dir = output, Set Data = 1
                             * This causes the output to go high.
                             */
                            ioDirection[0] |= VP880_IODIR_IO1_OUTPUT;
                            ioData[0] |= VP880_IODATA_IO1;
                        } else {
                            if ((pcn == VP880_DEV_PCN_88536) ||
                                (pcn == VP880_DEV_PCN_88264)) {
                                /*
                                 * Dir = output, Set Data = 0
                                 * This causes the output to go low.
                                 */
                                ioDirection[0] |= VP880_IODIR_IO1_OUTPUT;
                                ioData[0] &= ~VP880_IODATA_IO1;
                            } else {
                                /*
                                 * Dir = open drain, Set Data = 1
                                 * This causes the output to go low.
                                 */
                                ioDirection[0] |= VP880_IODIR_IO1_OPEN_DRAIN;
                                ioData[0] |= VP880_IODATA_IO1;
                            }
                        }
                    }
                    break;

                case VP_RELAY_RESET:
                    if (revCode <= VP880_REV_VC) {
                        ioDirection[0] |= VP880_IODIR_IO1_OPEN_DRAIN;
                        if ((termType == VP_TERM_FXS_ISOLATE) ||
                            (termType == VP_TERM_FXS_ISOLATE_LP)) {
                            /*
                             * Dir = open drain, Set Data = 1.
                             * This causes the output to go low
                             */
                            ioData[0] |= VP880_IODATA_IO1;
                        } else {
                            /*
                             * Dir = open drain, Set Data = 0
                             * This causes the output to go high.
                             */
                            ioData[0] &= ~VP880_IODATA_IO1;
                        }
                    } else {
                        /*
                         * Devices VP880_DEV_PCN_88536 and VP880_DEV_PCN_88264
                         * are affected here because the VP-API-II forces the
                         * revision code to >= JA
                         */
                        if ((termType == VP_TERM_FXS_ISOLATE) ||
                            (termType == VP_TERM_FXS_ISOLATE_LP)) {
                            if ((pcn == VP880_DEV_PCN_88536) ||
                                (pcn == VP880_DEV_PCN_88264)) {
                                /*
                                 * Dir = output, Set Data = 0.
                                 * This causes the output to go low
                                 */
                                ioDirection[0] |= VP880_IODIR_IO1_OUTPUT;
                                ioData[0] &= ~VP880_IODATA_IO1;
                            } else {
                                /*
                                 * Dir = open drain, Set Data = 1.
                                 * This causes the output to go low
                                 */
                                ioDirection[0] |= VP880_IODIR_IO1_OPEN_DRAIN;
                                ioData[0] |= VP880_IODATA_IO1;
                            }
                        } else {
                            /*
                             * Dir = output, Set Data = 1
                             * This causes the output to go high.
                             */
                            ioDirection[0] |= VP880_IODIR_IO1_OUTPUT;
                            ioData[0] |= VP880_IODATA_IO1;
                        }
                    }
                    break;

                default:
                    /* Restore values prior to caling this function. */
                    pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION] = preIcr1Values;

                    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                    VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
                    return VP_STATUS_INVALID_ARG;
            }
            break;

        default:
            /* Restore values prior to caling this function. */
            pLineObj->icr1Values[VP880_ICR1_TEST_LOAD_LOCATION] = preIcr1Values;

            VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
            VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
            return VP_STATUS_INVALID_ARG;
    }

    VP_LINE_STATE(VpLineCtxType, pLineCtx, ("1. Write IODATA 0x%02X on Ch %d",
        ioData[0], pLineObj->channelId));

    VP_LINE_STATE(VpLineCtxType, pLineCtx, ("2. Write IODIR 0x%02X on Channel %d",
        ioDirection[0], pLineObj->channelId));

    /*
     * Note in this ONE VP-API-II case for ICR1 Write, we don't go through
     * protected write because that's handled above in this function.
     */
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR1_WRT,
        VP880_ICR1_LEN, pLineObj->icr1Values);

    VP_LINE_STATE(VpLineCtxType, pLineCtx, ("Vp880SetRelayState(): Write ICR1 0x%02X 0x%02X 0x%02X 0x%02X Ch %d",
        pLineObj->icr1Values[0], pLineObj->icr1Values[1],
        pLineObj->icr1Values[2], pLineObj->icr1Values[3], pLineObj->channelId));

    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_IODATA_REG_WRT,
        VP880_IODATA_REG_LEN, ioData);

    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_IODIR_REG_WRT,
        VP880_IODIR_REG_LEN, ioDirection);

    /* send down the mpi commands */
    VpMpiCmdWrapper(deviceId, ecVal, mpiBuffer[0], mpiIndex-1, &mpiBuffer[1]);

    pLineObj->relayState = rState;

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);

    VP_API_FUNC_INT(VpLineCtxType, pLineCtx, ("Vp880SetRelayState-"));
    return VP_STATUS_SUCCESS;
}

/**
 * Vp880ApplyInternalTestTerm()
 *  Configures ICR settings for the internal test termination algorithm, which
 * is used instead of a physical test load for devices which do not have one.
 * The internal test termination works by internally shorting tip and ring.
 */
static void
Vp880ApplyInternalTestTerm(
    VpLineCtxType *pLineCtx)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    VpDevCtxType *pDevCtx = pLineCtx->pDevCtx;
    Vp880DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    uint8 ecVal = pLineObj->ecVal;
    uint16 timerDelay;
    uint8 icr1Reg[VP880_ICR1_LEN];

    uint8 mpiBuffer[3 + VP880_ICR6_LEN + VP880_ICR4_LEN + VP880_ICR1_LEN];
    uint8 mpiIndex = 0;

    if (pLineObj->internalTestTermApplied == TRUE) {
        return;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    /* Disconnect VAB sensing */
    pLineObj->icr6Values[VP880_DC_CAL_CUT_INDEX] |= VP880_C_TIP_SNS_CUT;
    pLineObj->icr6Values[VP880_DC_CAL_CUT_INDEX] |= VP880_C_RING_SNS_CUT;
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR6_WRT,
        VP880_ICR6_LEN, pLineObj->icr6Values);

    /* Reverse the polarity of the ground key detector to disable ground
     * key event */
    pLineObj->icr4Values[VP880_ICR4_GKEY_DET_LOCATION] |= VP880_ICR4_GKEY_POL;
    pLineObj->icr4Values[VP880_ICR4_GKEY_DET_LOCATION+1] |= VP880_ICR4_GKEY_POL;
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR4_WRT,
        VP880_ICR4_LEN, pLineObj->icr4Values);

    /*
     * Forcing the SLIC DC bias for 200ms helps collapse the battery voltage, especially for fixed
     * tracking designs.  We're taking over ICR1 completely here.  Other parts of the code will set
     * pLineObj->icr1Values but will not actually write to the register while this relay state is
     * active. See Vp880ProtectedWriteICR1(). When we leave this relay state, we will restore
     * pLineObj->icr1Values
     */
    icr1Reg[0] = 0xFF;
    icr1Reg[2] = 0xFF;
    if (pDevObj->stateInt & VP880_IS_ABS) {
#ifdef VP880_ABS_SUPPORT
        icr1Reg[1] = 0x68;
        icr1Reg[3] = 0x06;
#endif
    } else {
#ifdef VP880_TRACKER_SUPPORT
        icr1Reg[1] = 0xFF;
        icr1Reg[3] = 0x0F;
#endif
    }
    VP_LINE_STATE(VpLineCtxType, pLineCtx,
                  ("Vp880ApplyInternalTestTerm(): Write ICR1 0x%02X 0x%02X 0x%02X 0x%02X Ch %d",
                   icr1Reg[0], icr1Reg[1], icr1Reg[2], icr1Reg[3], pLineObj->channelId));
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR1_WRT, VP880_ICR1_LEN, icr1Reg);

    /* send down the mpi commands */
    VpMpiCmdWrapper(deviceId, ecVal, mpiBuffer[0], mpiIndex-1, &mpiBuffer[1]);

    /* Start a timer to change the ICR1 settings later to make tip and ring
     * outputs high impedance so that they tend to pull to battery. */
    if ((pDevObj->stateInt & VP880_IS_ABS) ||
        !(pDevObj->swParams[VP880_REGULATOR_TRACK_INDEX]
             & VP880_REGULATOR_FIXED_RING_SWY)) {
        /* Use a short delay for ABS and non-fixed tracking devices */
        timerDelay = VP880_INTERNAL_TESTTERM_SETTLING_TIME_SHORT;
    } else {
        /* Use a longer delay for fixed tracking devices */
        timerDelay = VP880_INTERNAL_TESTTERM_SETTLING_TIME_LONG;
    }
    pLineObj->lineTimers.timers.timer[VP_LINE_INTERNAL_TESTTERM_TIMER] =
        (MS_TO_TICKRATE(timerDelay, pDevObj->devProfileData.tickRate)) | VP_ACTIVATE_TIMER;

    pLineObj->internalTestTermApplied = TRUE;

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
} /* Vp880ApplyInternalTestTerm() */

/**
 * Vp880RemoveInternalTestTerm()
 *  This function reverts the settings that control the internal test
 * termination.
 */
static void
Vp880RemoveInternalTestTerm(
    VpLineCtxType *pLineCtx)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    VpDevCtxType *pDevCtx = pLineCtx->pDevCtx;
    Vp880DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    uint8 ecVal = pLineObj->ecVal;

    uint8 mpiBuffer[3 + VP880_ICR6_LEN + VP880_ICR4_LEN + VP880_ICR1_LEN];
    uint8 mpiIndex = 0;

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    /* Restore VAB sensing */
    pLineObj->icr6Values[VP880_DC_CAL_CUT_INDEX] &= ~VP880_C_TIP_SNS_CUT;
    pLineObj->icr6Values[VP880_DC_CAL_CUT_INDEX] &= ~VP880_C_RING_SNS_CUT;
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR6_WRT,
        VP880_ICR6_LEN, pLineObj->icr6Values);

    /* Restore ground key polarity setting */
    pLineObj->icr4Values[VP880_ICR4_GKEY_DET_LOCATION] &= ~VP880_ICR4_GKEY_POL;
    pLineObj->icr4Values[VP880_ICR4_GKEY_DET_LOCATION+1] &= ~VP880_ICR4_GKEY_POL;
    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR4_WRT,
        VP880_ICR4_LEN, pLineObj->icr4Values);

    /* Restore ICR1 to the cached value in pLineObj->icr1Values */
    VP_LINE_STATE(VpLineCtxType, pLineCtx, ("Vp880RemoveInternalTestTerm(): Write ICR1 0x%02X 0x%02X 0x%02X 0x%02X Ch %d",
        pLineObj->icr1Values[0], pLineObj->icr1Values[1],
        pLineObj->icr1Values[2], pLineObj->icr1Values[3], pLineObj->channelId));

    mpiIndex = VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR1_WRT,
        VP880_ICR1_LEN, pLineObj->icr1Values);

    /* send down the mpi commands */
    VpMpiCmdWrapper(deviceId, ecVal, mpiBuffer[0], mpiIndex-1, &mpiBuffer[1]);

    /* Deactivate the timer in case it is still running */
    pLineObj->lineTimers.timers.timer[VP_LINE_INTERNAL_TESTTERM_TIMER]
        &= ~VP_ACTIVATE_TIMER;

    pLineObj->internalTestTermApplied = FALSE;

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
} /* Vp880RemoveInternalTestTerm() */

/**
 * Vp880OffHookMgmt()
 *  This function manages the device and API behavior when an off-hook is
 * detected from the device AFTER all normal debounce timers have expired.
 *
 * Preconditions:
 *  This function is called internally by the API-II only.
 *
 * Postconditions:
 *  Device and API is updated accordingly. Returns TRUE if an event is posted.
 */
bool
Vp880OffHookMgmt(
    Vp880DeviceObjectType *pDevObj,
    VpLineCtxType *pLineCtx,
    uint8 ecVal)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    bool retFlag = FALSE;

#ifdef VP_CSLAC_SEQ_EN
    VpProfilePtrType pCadence;
#endif

    VP_HOOK(VpLineCtxType, pLineCtx, ("Off-Hook on Line %d at Time %d Low Power 0x%02X",
        pLineObj->channelId, pDevObj->timeStamp, (pLineObj->status & VP880_LOW_POWER_EN)));

    pLineObj->dpStruct.hookSt = TRUE;
    pLineObj->dpStruct2.hookSt = TRUE;

    pLineObj->leakyLineCnt = 0;
    pLineObj->status &= ~VP880_LINE_LEAK;

    if(pLineObj->pulseMode == VP_OPTION_PULSE_DECODE_OFF) {
        pLineObj->lineEvents.signaling |= VP_LINE_EVID_HOOK_OFF;
        pLineObj->lineEventHandle = pDevObj->timeStamp;
        retFlag = TRUE;
    }

#ifdef VP_CSLAC_SEQ_EN
    /*
     * If an off-hook is detected when the active cadence is a Message Waiting
     * Pulse on the line, restore the line state.
     */
    pCadence = pLineObj->cadence.pActiveCadence;
    if (pCadence != VP_PTABLE_NULL) {
        if (pCadence[VP_PROFILE_TYPE_LSB] == VP_PRFWZ_PROFILE_MSG_WAIT_PULSE_INT) {
            VP_LINE_STATE(VpLineCtxType, pLineCtx, ("Stopping Active Message Waiting Pulse"));
            Vp880SetLineState(pLineCtx, pLineObj->lineState.currentState);
        }
    }
#endif
    return retFlag;
}

/**
 * Vp880OnHookMgmt()
 *  This function manages the device and API behavior when an on-hook is
 * detected from the device AFTER all normal debounce timers have expired.
 *
 * Preconditions:
 *  This function is called internally by the API-II only.
 *
 * Postconditions:
 *  Device and API is updated accordingly.
 */
bool
Vp880OnHookMgmt(
    Vp880DeviceObjectType *pDevObj,
    VpLineCtxType *pLineCtx,
    uint8 ecVal)
{
    Vp880LineObjectType *pLineObj = pLineCtx->pLineObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    bool retFlag = FALSE;

#ifdef VP880_ABS_SUPPORT
    uint8 slacState;
#endif

    VP_HOOK(VpLineCtxType, pLineCtx, ("On-Hook on Line %d at Time %d",
        pLineObj->channelId, pDevObj->timeStamp));

    /* Restore the initial threshold */
    if (pLineObj->hookHysteresis != 0) {
        VpMpiCmdWrapper(deviceId, ecVal, VP880_LOOP_SUP_WRT, VP880_LOOP_SUP_LEN,
            pLineObj->loopSup);
    }

    pLineObj->dpStruct.hookSt = FALSE;
    pLineObj->dpStruct2.hookSt = FALSE;

    if ((pLineObj->pulseMode == VP_OPTION_PULSE_DECODE_OFF) &&
        (!(pLineObj->status & VP880_LINE_LEAK))) {
        /*
         * If this is the first time after initialization that we are checking
         * for on-hook and it is on-hook, don't generate an interrupt
         */
        VP_HOOK(VpLineCtxType, pLineCtx,
            ("Dial Pulse Detect Disabled - checking initial on-hook.."));

        if (!(pLineObj->lineState.condition & VP_CSLAC_STATUS_VALID)) {
            VP_HOOK(VpLineCtxType, pLineCtx,
                ("Line Previously Initialized - Generating On-Hook Event"));

            pLineObj->lineEvents.signaling |= VP_LINE_EVID_HOOK_ON;
            pLineObj->lineEventHandle = pDevObj->timeStamp;
            retFlag = TRUE;
        }
    } else {
        VP_HOOK(VpLineCtxType, pLineCtx,
            ("Dial Pulse Detect Enabled. On-Hook from Dial Pulse State Machine."));
    }
    if (VpIsLowPowerTermType(pLineObj->termType)) {
        VP_HOOK(VpLineCtxType, pLineCtx, ("User State %d Current State %d",
            pLineObj->lineState.usrCurrent, pLineObj->lineState.currentState));

        if (pLineObj->lineState.usrCurrent == VP_LINE_STANDBY) {
            pLineObj->lineState.currentState = VP_LINE_STANDBY;
            Vp880LLSetSysState(deviceId, pLineCtx, 0x00, FALSE);
        }
    }

#ifdef VP880_ABS_SUPPORT
    slacState = pLineObj->slicValueCache;

    if (pDevObj->stateInt & VP880_IS_ABS) {
        switch(slacState & VP880_SS_LINE_FEED_MASK) {
            /*
             * Feed states where the SLIC needs to be put into high battery mode
             * to optimize feed conditions and transient response.
             */
            case (VP880_SS_ACTIVE & VP880_SS_LINE_FEED_MASK):
            case (VP880_SS_IDLE & VP880_SS_LINE_FEED_MASK):
            case (VP880_SS_ACTIVE_MID_BAT & VP880_SS_LINE_FEED_MASK):
                slacState &= ~VP880_SS_LINE_FEED_MASK;
                if(pLineObj->lineState.usrCurrent == VP_LINE_STANDBY) {
                    slacState |= VP880_SS_IDLE;
                } else {
                    slacState |= VP880_SS_ACTIVE_MID_BAT;
                }
                Vp880LLSetSysState(deviceId, pLineCtx, slacState, TRUE);
                break;

            default:
                /*
                 * Another state that either should not cause off-hook detection,
                 * or state that is handled by API-II functionality (e.g.,
                 * Ring Trip).
                 */
                break;
        }
    }
#endif

    return retFlag;
}

/*
 * Vp880ProtectedWriteICR1()
 *  This function is a wrapper for writing to ICR1.  If the internal test
 * termination is applied, ICR1 must not be changed, so this function copies
 * the data into the line object cache and returns without writing anything to
 * the device.  If the internal test termination is not applied, the write
 * is performed.
 *
 * Note: This function must be called from within a critical section.
 */
#ifdef VP880_FXS_SUPPORT
uint8
Vp880ProtectedWriteICR1(
    Vp880LineObjectType *pLineObj,
    uint8 mpiIndex,
    uint8 *mpiBuffer)
{
    if (pLineObj->internalTestTermApplied == FALSE) {
        VP_LINE_STATE(None, VP_NULL, ("Vp880ProtectedWriteICR1(): Channel %d Writing ICR1 0x%02X 0x%02X 0x%02X 0x%02X",
            pLineObj->channelId,
            pLineObj->icr1Values[0], pLineObj->icr1Values[1],
            pLineObj->icr1Values[2], pLineObj->icr1Values[3]));

        return VpCSLACBuildMpiBuffer(mpiIndex, mpiBuffer, VP880_ICR1_WRT,
            VP880_ICR1_LEN, pLineObj->icr1Values);
    }
    return mpiIndex;
}
#endif  /* VP880_FXS_SUPPORT */
#endif
