Exemplo n.º 1
0
/**
 * VpMake790LineObject()
 *  This function initializes a line context using the information that is
 * passed. This function is like a C++ constructor. It initializes the passed
 * line context and line object based on the paramters provided. The passed line
 * object type should match with the type of device object type. See VP-API
 * reference guide for more information.
 *
 * Preconditions:
 *  This function assumes device context has already been created and
 * initialized. This function should only be called after downloading the boot
 * image the device when applicable (like for VCP class of devices).
 *
 * Postconditions:
 *  This function initializes the line context/line object. Line related VP-API
 * functions can be called after calling this function.
 */
VpStatusType
Vp790MakeLineObject(
    VpTermType termType,
    uint8 channelId,
    VpLineCtxType *pLineCtx,
    void *pVoidLineObj,
    VpDevCtxType *pDevCtx)
{
    Vp790LineObjectType *pLineObj = pVoidLineObj;
    Vp790DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;

    if (channelId >= pDevObj->staticInfo.maxChannels) {
        return VP_STATUS_INVALID_ARG;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    Vp790InitLineObject(pLineObj);

    switch (termType) {
        case VP_TERM_FXS_GENERIC:
        case VP_TERM_FXS_75282:
        case VP_TERM_FXS_TO_TL:
        case VP_TERM_FXS_RR:
            pLineObj->termType = termType;
            break;

        default:
            VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
            return VP_STATUS_INVALID_ARG;
    }

    pLineCtx->pLineObj = pLineObj;
    pLineCtx->pDevCtx = pDevCtx;

    pDevCtx->pLineCtx[channelId] = pLineCtx;
    pLineObj->channelId = channelId;

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);

    /* Everything else done by device/line specific functions */
    return VP_STATUS_SUCCESS;
}
Exemplo n.º 2
0
/**
 * VpMpiCmd()
 *  This function executes a Device MPI command through the MPI port. It
 * executes both read and write commands. The read or write operation is
 * determined by the "cmd" argument (odd = read, even = write). The caller must
 * ensure that the data array is large enough to hold the data being collected.
 * Because this command used hardware resources, this procedure is not
 * re-entrant.
 *
 * Note: For API-II to support multi-threading, this function has to write to
 * the EC register of the device to set the line being controlled, in addition
 * to the command being passed. The EC register write/read command is the same
 * for every CSLAC device and added to this function. The only exception is
 * if the calling function is accessing the EC register (read), in which case
 * the EC write cannot occur.
 *
 * This example assumes the implementation of two byte level commands:
 *
 *    MpiReadByte(VpDeviceIdType deviceId, uint8 *data);
 *    MpiWriteByte(VpDeviceIdType deviceId, uint8 data);
 *
 * Preconditions:
 *  The device must be initialized.
 *
 * Postconditions:
 *   The data pointed to by dataPtr, using the command "cmd", with length
 * "cmdLen" has been sent to the MPI bus via the chip select associated with
 * deviceId.
 */
void
VpMpiCmd(
    VpDeviceIdType deviceId,    /**< Chip select, connector and 3 or 4 wire
                                 * interface for command
                                 */
    uint8 ecVal,        /**< Value to write to the EC register */
    uint8 cmd,          /**< Command number */
    uint8 cmdLen,       /**< Number of bytes used by command (cmd) */
    uint8 *dataPtr)     /**< Pointer to the data location */
{
   zarlink_device_id_t *z = (zarlink_device_id_t *)(deviceId);
   uint8 isRead = (cmd & READ_COMMAND);
   uint8 buf[4];
   uint8 buf_len = 0;

#define CSLAC_EC_REG_RD    0x4B   /* Same for all CSLAC devices */
#define CSLAC_EC_REG_WRT   0x4A   /* Same for all CSLAC devices */
#define CSLAC_EC_REG_LEN   0x01   /* Same for all CSLAC devices */
   /* Configure glue logic as necessary to talk to the device */
   /* Start critical section for MPI access */
   VpSysEnterCritical(deviceId, VP_MPI_CRITICAL_SEC);
   /* If a EC read is being preformed don't set the EC register */
   if (CSLAC_EC_REG_RD != cmd) {
      buf[buf_len] = CSLAC_EC_REG_WRT;
      buf_len += 1;
      buf[buf_len] = ecVal;
      buf_len += 1;
   }
   /* Write the command byte to MPI. */
   buf[buf_len] = cmd;
   buf_len += 1;

   if (isRead) {
      bcm_mpi_read(z->mpi, dataPtr, cmdLen, buf, buf_len);
   }
   else {
      /* If writing, access data from buffer passed and write to MPI */
      bcm_mpi_write(z->mpi, buf, buf_len);
      bcm_mpi_write(z->mpi, dataPtr, cmdLen);
   }
   VpSysExitCritical(deviceId, VP_MPI_CRITICAL_SEC);

   return;
} /* End VpMpiCmd */
Exemplo n.º 3
0
/**
 * Vp790InitProfile
 *  This function is used to initialize profile tables in Vp790.
 *
 * Preconditions:
 *  The device associated with this line must be initialized.
 *
 * Postconditions:
 *  The line pointed to by the line context passed is initialized with the
 * profile data specified.  This function returns the success code if the device
 * associated with this line is initialized and the index being specified is
 * within the range of the device profile table.
 */
VpStatusType
Vp790InitProfile(
    VpDevCtxType *pDevCtx,
    VpProfileType type,
    VpProfilePtrType pProfileIndex,
    VpProfilePtrType pProfile)
{
    Vp790DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    VpStatusType status = VP_STATUS_SUCCESS;

    /*
     * If the profile passed is an index, indicated by Get Profile Index return
     * value of > -1, return an error (cannot init an indexed entry with an
     * index).
     */
    int profileIndex = VpGetProfileIndex(pProfile);

    if (profileIndex >= 0) {
        return VP_STATUS_INVALID_ARG;
    }

    /*
     * If pProfileIndex is -1, the profile is of pointer type and invalid,
     * otherwise it is an index.  If it's an index, make sure the range is
     * valid.
     */
    profileIndex = VpGetProfileIndex(pProfileIndex);
    if (profileIndex < 0) {
        return VP_STATUS_INVALID_ARG;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);
    /*
     * The correct types are passed, but check to make sure the specific profile
     * type being initialized is valid as well as the index value
     */
    switch(type) {
        case VP_PROFILE_DEVICE:
            if (profileIndex > VP_CSLAC_DEV_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pDevProfileTable[profileIndex] =
                        pProfile;
            }
            break;

        case VP_PROFILE_AC:
            if (profileIndex > VP_CSLAC_AC_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pAcProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_DC:
            if (profileIndex > VP_CSLAC_DC_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pDcProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_RING:
            if (profileIndex > VP_CSLAC_RINGING_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pRingingProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_RINGCAD:
            if (profileIndex > VP_CSLAC_RING_CADENCE_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pRingingCadProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_TONE:
            if (profileIndex > VP_CSLAC_TONE_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pToneProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_TONECAD:
            if (profileIndex > VP_CSLAC_TONE_CADENCE_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pToneCadProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_METER:
            if (profileIndex > VP_CSLAC_METERING_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pMeteringProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_CID:
            if (profileIndex > VP_CSLAC_CALLERID_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pCallerIdProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        case VP_PROFILE_FXO_CONFIG:
            if (profileIndex > VP_CSLAC_FXO_CONFIG_PROF_TABLE_SIZE) {
                status = VP_STATUS_INVALID_ARG;
            } else {
                pDevObj->devProfileTable.pFxoConfigProfileTable[profileIndex] =
                    pProfile;
            }
            break;

        default:
            status = VP_STATUS_INVALID_ARG;
            break;
    }

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
    return status;

} /* Vp790InitProfile() */
Exemplo n.º 4
0
/**
 * Vp790ConfigLine
 *  This function reloads a line of a device with the specified parameters.
 *
 * Preconditions:
 *  The device associated with this line must be initialized.
 *
 * Postconditions:
 *  The line pointed to by the line context passed is initialized with the
 * profile data specified.  This function returns the success code if the device
 * associated with this line is initialized.
 */
VpStatusType
Vp790ConfigLine(
    VpLineCtxType *pLineCtx,
    VpProfilePtrType pAcProfile,    /**< Pointer to AC coefficient data or
                                     * profile index to be applied to this line.
                                     */

    VpProfilePtrType pDcOrFxoProfile,   /**< Pointer to DC Feed (FXS) or Cfg
                                         * (FX0) profile or profile index to be
                                         * applied to this line.
                                         */

    VpProfilePtrType pRingProfile)  /**< Pointer to Ringing profile or profile
                                     * index to apply to this line
                                     */
{
    Vp790LineObjectType *pLineObj = pLineCtx->pLineObj;
    VpDevCtxType *pDevCtx = pLineCtx->pDevCtx;
    Vp790DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpProfileDataType *pCurrentProf;
    uint8 profIndex = VP_PROFILE_MPI_LEN;
    uint8 ioReg[VP790_IO_REG_LEN];
    uint8 ccr4[VP790_CCR4_LEN], ccr4Temp[VP790_CCR4_LEN];
    uint8 defaultVals[VP790_LOOP_SUP_LEN] =
        {0x0D, 0x64, 0x0D, 0x01, 0x30, 0x00, 0x10, 0x0D};

    uint8 ecVal[] = {VP790_EC_CH1, VP790_EC_CH2, VP790_EC_CH3, VP790_EC_CH4};
    uint8 channelId = pLineObj->channelId;
    VpDeviceIdType deviceId = pDevObj->deviceId;

    VpProfilePtrType pAcProf = VP_PTABLE_NULL;
    VpProfilePtrType pDcFxoCfgProf = VP_PTABLE_NULL;
    VpProfilePtrType pRingProf = VP_PTABLE_NULL;

    /* Proceed if initialized or in progress, and not calibrating */
    if (pDevObj->status.state & (VP_DEV_INIT_CMP | VP_DEV_INIT_IN_PROGRESS)) {
        if (pDevObj->status.state & VP_DEV_IN_CAL) {
            return VP_STATUS_DEVICE_BUSY;
        }
    } else {
        return VP_STATUS_DEV_NOT_INITIALIZED;
    }

    /* Check the legality of the AC profile */
    if (!VpCSLACIsProfileValid(VP_PROFILE_AC,
            VP_CSLAC_AC_PROF_TABLE_SIZE, pDevObj->profEntry.acProfEntry,
            pDevObj->devProfileTable.pAcProfileTable, pAcProfile, &pAcProf)) {

        return VP_STATUS_ERR_PROFILE;
    }

    /* Check the legality of the DC profile */
    if (!VpCSLACIsProfileValid(VP_PROFILE_DC, VP_CSLAC_DC_PROF_TABLE_SIZE,
            pDevObj->profEntry.dcProfEntry,
            pDevObj->devProfileTable.pDcProfileTable,
            pDcOrFxoProfile, &pDcFxoCfgProf)) {

        return VP_STATUS_ERR_PROFILE;
    }

    /* Check the legality of the Ringing profile */
    if (!VpCSLACIsProfileValid(VP_PROFILE_RING, VP_CSLAC_RINGING_PROF_TABLE_SIZE,
            pDevObj->profEntry.ringingProfEntry,
            pDevObj->devProfileTable.pRingingProfileTable, pRingProfile,
            &pRingProf)) {

        return VP_STATUS_ERR_PROFILE;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    /* If no AC Profile exists use whatever exists in the device */
    if (pAcProfile != VP_PTABLE_NULL) {
        pCurrentProf = (VpProfileDataType *)pAcProfile;
        VpMpiCmdWrapper(deviceId, ecVal[channelId], NOOP_CMD, pCurrentProf[profIndex],
            &pCurrentProf[profIndex + 1]);
    }

    /*
     * The Ring Profile may contain content (command 0x68) that affects
     * bits controlled only by the API-II. So read the register first, then
     * determine what bits are allowed to change, and set the register to
     * the new value.
     */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_CCR4_RD, VP790_CCR4_LEN,
        ccr4Temp);

    /* If no Ringing Profile exists use whatever exists in the device */
    if (pRingProfile != VP_PTABLE_NULL) {
        pCurrentProf = (VpProfileDataType *)pRingProfile;
        VpMpiCmdWrapper(deviceId, ecVal[channelId], NOOP_CMD, pCurrentProf[profIndex],
            &pCurrentProf[profIndex + 1]);
    }

    /*
     * Read what ccr4 is now set to. We'll need to adjust because some bits
     * may not be allowed to be changed by the Ringing Profile
     */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_CCR4_RD, VP790_CCR4_LEN,
        ccr4);

    /* Zero out those bits not controlled by the profile */
    ccr4[0] &= (VP790_EXT_RINGING | VP790_CCR4_RTM);

    /*
     * Or in the bits controlled by API-II as they existed before this profile
     * was sent.
     */
    ccr4Temp[0] &= (uint8)(~(VP790_EXT_RINGING | VP790_CCR4_RTM));
    ccr4[0] |= ccr4Temp[0];

    /*
     * If we are set to external ringing, RD2 has to be set for auto mode.
     * Otherwise it's set for manual
     */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_IO_REG_RD, VP790_IO_REG_LEN,
        ioReg);

    /* Set remaining values of ccr4 based on API-II settings */
    if (ccr4[0] & VP790_EXT_RINGING) {
        ioReg[0] |= VP790_IO_REG_RD2_AUTO;

        if(pLineObj->ringCtrl.zeroCross == VP_OPTION_ZC_NONE) {
            ccr4[0] |= VP790_CCR4_ZXR_DIS;
        } else {
            ccr4[0] &= ~VP790_CCR4_ZXR_DIS;
        }
    } else {
        ioReg[0] &= ~VP790_IO_REG_RD2_AUTO;

        if(pLineObj->ringCtrl.zeroCross == VP_OPTION_ZC_NONE) {
            ccr4[0] &= ~VP790_CCR4_ZXR_DIS;
        } else {
            ccr4[0] |= VP790_CCR4_ZXR_DIS;
        }
    }
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_CCR4_WRT, VP790_CCR4_LEN,
        ccr4);

    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_IO_REG_WRT,
        VP790_IO_REG_LEN, ioReg);

    /* If no DC Feed Profile exists use whatever the device default value is */
    if (pDcFxoCfgProf != VP_PTABLE_NULL) {
        pCurrentProf = (VpProfileDataType *)pDcFxoCfgProf;
        VpMpiCmdWrapper(deviceId, ecVal[channelId], NOOP_CMD, pCurrentProf[profIndex],
            &pCurrentProf[profIndex + 1]);
    } else {
        VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_LOOP_SUP_WRT,
            VP790_LOOP_SUP_LEN, defaultVals);
    }

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
    return VP_STATUS_SUCCESS;
}
Exemplo n.º 5
0
/**
 * Vp790InitLine
 *  This function initializes a line of a device with the specified parameters
 * and API default values. It is a "Line Reset".
 *
 * Preconditions:
 *  The device associated with this line must be initialized.
 *
 * Postconditions:
 *  The line pointed to be the line context passed is initialized with the
 * profile data specified.  This function returns the success code if the device
 * associated with this line is initialized.
 */
VpStatusType
Vp790InitLine(
    VpLineCtxType *pLineCtx,
    VpProfilePtrType pAcProfile,    /**< Pointer to AC coefficient data or
                                     * profile index to be applied to this line.
                                     */

    VpProfilePtrType pDcOrFxoProfile,   /**< Pointer to DC Feed (FXS) or Cfg
                                         * (FX0) profile or profile index to be
                                         * applied to this line.
                                         */

    VpProfilePtrType pRingProfile)  /**< Pointer to Ringing profile or profile
                                     * index to apply to this line
                                     */
{
    Vp790LineObjectType *pLineObj = pLineCtx->pLineObj;
    VpDevCtxType *pDevCtx = pLineCtx->pDevCtx;
    Vp790DeviceObjectType *pDevObj = pDevCtx->pDevObj;

    uint8 ecVal[] = {VP790_EC_CH1, VP790_EC_CH2, VP790_EC_CH3, VP790_EC_CH4};
    uint8 channelId = pLineObj->channelId;
    uint8 data;

#ifdef VP_CSLAC_SEQ_EN
    uint8 seqByte;
#endif

    uint8 ioReg[VP790_IO_REG_LEN];
    uint8 disableVals[VP790_LOOP_SUP_LEN] =
        {0x0D, 0x64, 0x0D, 0x01, 0x30, 0x00, 0x00, 0x7F};

    VpDeviceIdType deviceId = pDevObj->deviceId;

    /* Proceed if initialized or in progress, and not calibrating */
    if (pDevObj->status.state & (VP_DEV_INIT_CMP | VP_DEV_INIT_IN_PROGRESS)) {
        if (pDevObj->status.state & VP_DEV_IN_CAL) {
            return VP_STATUS_DEVICE_BUSY;
        }
    } else {
        return VP_STATUS_DEV_NOT_INITIALIZED;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

#ifdef VP_CSLAC_SEQ_EN
    for (seqByte = 0; seqByte < VP790_INT_SEQ_LEN; seqByte++) {
        pLineObj->intSequence[seqByte] = 0x00;
    }

    pLineObj->callerId.status = VP_CID_RESET_VALUE;

    pLineObj->thisFskCid = FALSE;
#endif

    pLineObj->pRingingCadence = VP_PTABLE_NULL;
    pLineObj->pCidProfileType1 = VP_PTABLE_NULL;
    pLineObj->pCidProfileType2 = VP_PTABLE_NULL;

    pLineObj->lineState.currentState = VP_LINE_DISCONNECT;
    pLineObj->lineState.previous = VP_LINE_DISCONNECT;

    pLineObj->codec = VP_NUM_OPTION_CODEC_TYPE_IDS;

    pLineObj->lineTimers.type = VP_CSLAC_FXS_TIMER;
    InitTimerVars(pLineCtx);

#ifdef VP_CSLAC_SEQ_EN
    VpMemSet(&pLineObj->cadence, 0, sizeof(VpSeqDataType));
#endif

    /* Software reset the channel */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_SW_RESET_CMD, NO_DATA, &data);
    VpSysWait(3);

    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_LOOP_SUP_WRT,
        VP790_LOOP_SUP_LEN, disableVals);

    VpSysWait(1);

    /* Set the default line state */
    Vp790SetLineState(pLineCtx, VP_LINE_DISCONNECT);

    /* Deactiveate the CODEC for the channel */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_DEACTIVATE_CMD, NO_DATA, &data);

    /***************** C3 Operational Issue 3 ******************/
    /* This errata fix does not harm D3 operation */
    data = 0x00;
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_CCR9_WRT, VP790_CCR9_LEN, &data);

    /* We've already deactivated the device */
    VpSysWait(3);
    /**************** End Operational Issue 3 ******************/

    pLineObj->ringCtrl.zeroCross = VP_OPTION_DEFAULT_ZERO_CROSS;
    Vp790ConfigLine(pLineCtx, pAcProfile, pDcOrFxoProfile, pRingProfile);

    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_IO_REG_RD,
        VP790_IO_REG_LEN, ioReg);
    ioReg[0] |= VP790_IO_REG_RD1_MANUAL;
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_IO_REG_WRT,
        VP790_IO_REG_LEN, ioReg);

    VpImplementDefaultSettings(VP_NULL, pLineCtx);

    /* Force an initial test of the hook state */
    pLineObj->lineState.condition = VP_CSLAC_STATUS_INVALID;
    pLineObj->dpStruct.hookSt = FALSE;

    VpInitDP(&pLineObj->dpStruct);

    /* Re-activate the channel due to a silicon bug -- and it doesn't hurt */
    VpMpiCmdWrapper(deviceId, ecVal[channelId], VP790_ACTIVATE_CMD, NO_DATA,
        VP_NULL);

    /* Post the line init complete event */
    pLineObj->lineEvents.response |= VP_LINE_EVID_LINE_INIT_CMP;

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
    return VP_STATUS_SUCCESS;
} /* Vp790InitLine */
Exemplo n.º 6
0
/**
 * Vp790InitDevice
 *  This function initializes the device and all lines associated with this
 * device (if line profiles are passed to this function).
 *
 * Preconditions:
 *  None (device context is not NULL and is of Vp790 type, which is handled in
 * higher level software)
 *
 * Postconditions:
 *  This device is initialized to the configuration specified in the device
 * profile and the FXS lines associated with this device are initialized by the
 * FXS specific AC, DC, and Ringing profiles passed. This function returns an
 * error code if the device profile trying to be used for initialization is
 * VP_PTABLE_NULL (either passed or by a non-initialized index).
 */
VpStatusType
Vp790InitDevice(
    VpDevCtxType *pDevCtx,
    VpProfilePtrType pDevProfile,   /**< The profile pointer for the device
                                     * configuration parameters
                                     */
    VpProfilePtrType pAcProfile,    /**< The profile pointer (or index) for
                                     * the AC characteristic to apply to the
                                     * FXS lines
                                     */
    VpProfilePtrType pDcProfile,    /**< The profile pointer (or index) for
                                     * the DC characteristic to apply to the
                                     * FXS lines
                                     */
    VpProfilePtrType pRingProfile,  /**< The profile pointer (or index) for
                                     * the Ringing characteristic to apply to
                                     * the FXS lines
                                       */
    VpProfilePtrType pFxoAcProfile, /**< The profile pointer (or index) for
                                     * the AC characteristic to apply to the
                                     * FXO lines
                                       */
    VpProfilePtrType pFxoCfgProfile)/**< The profile pointer for the FXO
                                     * specific supervision paramaters.
                                     */
{
    VpLineCtxType *pLineCtx;
    Vp790DeviceObjectType *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType deviceId = pDevObj->deviceId;
    uint8 ecVal[] = {VP790_EC_CH1, VP790_EC_CH2, VP790_EC_CH3, VP790_EC_CH4};

    uint8 gpioDir[] = {VP790_GIO_DIR_ALL_OUTPUT};

    uint8 maxChan = pDevObj->staticInfo.maxChannels;
    VpProfilePtrType pDevProf;
    uint8 chan;

    VpStatusType status = VP_STATUS_SUCCESS;

    int profIndex = VpGetProfileIndex(pDevProfile);

    /*
     * Get Profile Index returns -1 if the profile passed is a pointer or
     * of VP_PTABLE_NULL type. Otherwise it returns the index
     */
    if (profIndex < 0) {
        /*
         * A pointer is passed or VP_PTABLE_NULL.  If it's a pointer, make
         * sure the content is valid for the profile type.
         */
        if (pDevProfile != VP_PTABLE_NULL) {
            if(VpVerifyProfileType(VP_PROFILE_DEVICE, pDevProfile) != TRUE) {
                return VP_STATUS_ERR_PROFILE;
            }
        }
        pDevProf = pDevProfile;

    } else if (profIndex < VP_CSLAC_DEV_PROF_TABLE_SIZE) {
        pDevProf = pDevObj->devProfileTable.pDevProfileTable[profIndex];

        if ((pDevProf == VP_PTABLE_NULL)
         || (!(pDevObj->profEntry.devProfEntry & (0x01 << profIndex)))) {
            return VP_STATUS_ERR_PROFILE;
        }
    } else {
        return VP_STATUS_ERR_PROFILE;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    pDevObj->status.globStatReg = 0;
    pDevObj->status.calibrating = 0;
    pDevObj->timeStamp = 0;
    pDevObj->status.state = VP_DEV_INIT_IN_PROGRESS;

    if (pDevProf != VP_PTABLE_NULL) {
        pDevObj->devProfileData.pcmClkRate =
            (uint16)(((pDevProf[VP790_DEV_PROFILE_PCLK_MSB] << 8) & 0xFF00)
                    | (pDevProf[VP790_DEV_PROFILE_PCLK_LSB] & 0x00FF));

        pDevObj->devProfileData.devCfg1 =
            (uint8)(pDevProf[VP790_DEV_PROFILE_DEVCFG1]);
        pDevObj->devProfileData.mClkCorrection =
            (uint8)(pDevProf[VP790_DEV_PROFILE_MCLK_CORR]);
        pDevObj->devProfileData.clockSlot =
            (uint8)(pDevProf[VP790_DEV_PROFILE_CLOCK_SLOT]);
        pDevObj->devProfileData.maxNumInterrupts =
            (uint8)(pDevProf[VP790_DEV_PROFILE_MAX_EVENTS]);

        pDevObj->devProfileData.tickRate =
            (uint16)(((pDevProf[VP790_DEV_PROFILE_TICKRATE_MSB] << 8) & 0xFF00)
                    | (pDevProf[VP790_DEV_PROFILE_TICKRATE_LSB] & 0x00FF));

        pDevObj->devProfileData.calibrationTime =
            MS_TO_TICKRATE(20, pDevObj->devProfileData.tickRate);
    } else {
        pDevObj->status.state &= ~VP_DEV_INIT_IN_PROGRESS;
        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
        return VP_STATUS_ERR_PROFILE;
    }

    /* Initialize device */
    /*
     * If not successful, the Clock Fail bit did not clear so return error code
     */
    if ((status = Vp790Init(pDevCtx)) != VP_STATUS_SUCCESS) {
        pDevObj->status.state &= ~(VP_DEV_INIT_IN_PROGRESS | VP_DEV_INIT_CMP);
        /*
         * Clear the tickRate, which is used by VpApiTick() to indicate VpInitDevice() was
         * completed. This prevents VpApiTick() from generating events on a non-initialized device
         * context/object.
         */
        pDevObj->devProfileData.tickRate = 0;
        VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
        return status;
    }

    VpMpiCmdWrapper(deviceId, ecVal[0], VP790_GIO_DIR_WRT, VP790_GIO_DIR_LEN, gpioDir);

    if (pDevProf[VP_PROFILE_VERSION] >=
        VP_CSLAC_DEV_PROFILE_VERSION_LINECARD_PARAM) {
        /* This profile contains the Linecard parameters value */
        VpMpiCmdWrapper(deviceId, ecVal[0], VP790_LINECARD_PARAM_WRT,
            VP790_LINECARD_PARAM_LEN,
            (VpProfileDataType *)(&pDevProf[VP790_DEV_PROFILE_LINECARD_PARAM_DATA0]));
    }

    /* Initialize each channel */
    for (chan = 0; chan < maxChan; chan++) {
        /*
         * For Init Line to work, the device cannot be non-initialized because
         * the init line function tries to set the line state.  Therefore,
         * temporarily set the device init flag to TRUE then immediately after
         * line init, set back to FALSE until device init is complete
         */
        pLineCtx = pDevCtx->pLineCtx[chan];
        if (pLineCtx != VP_NULL) {
            status = Vp790InitLine(pLineCtx, pAcProfile, pDcProfile,
                pRingProfile);

            if (status != VP_STATUS_SUCCESS) {
                pDevObj->status.state &=
                    ~(VP_DEV_INIT_IN_PROGRESS | VP_DEV_INIT_CMP);
                /*
                 * Clear the tickRate, which is used by VpApiTick() to indicate VpInitDevice() was
                 * completed. This prevents VpApiTick() from generating events on a non-initialized
                 * device context/object.
                 */
                pDevObj->devProfileData.tickRate = 0;
                VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                return status;
            }
        }
    }

    VpImplementDefaultSettings(pDevCtx, VP_NULL);

    /*
     * This clears the Init Line Events and any other erroneous event that
     * may have been created due to initialization
     */
    Vp790FlushEvents(pDevCtx);

    /* Start the device Calibration */
    Vp790CalCodecInt(pDevCtx);

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);

    return VP_STATUS_SUCCESS;
} /* Vp790InitDevice */
Exemplo n.º 7
0
/*******************************************************************************
 * Vp890MakeLineObject()
 * This function
 *
 * Arguments:
 *
 * Preconditions:
 *
 * Postconditions:
 ******************************************************************************/
VpStatusType
Vp890MakeLineObject(
    VpTermType              termType,
    uint8                   channelId,
    VpLineCtxType           *pLineCtx,
    void                    *pVoidLineObj,
    VpDevCtxType            *pDevCtx)
{
    Vp890LineObjectType       *pLineObj = pVoidLineObj;
    Vp890DeviceObjectType     *pDevObj = pDevCtx->pDevObj;
    VpDeviceIdType            deviceId = pDevObj->deviceId;

    /* Basic error checking */
    if (channelId >= pDevObj->staticInfo.maxChannels) {
        VP_ERROR(VpDevCtxType, pDevCtx, ("Vp890MakeLineObject() - Bad channelId"));
        return VP_STATUS_INVALID_ARG;
    }
    if (VP_NUM_TERM_TYPES < termType) {
        VP_ERROR(VpDevCtxType, pDevCtx, ("Vp890MakeLineObject() - Termination type outside range"));
        return  VP_STATUS_ERR_VTD_CODE;
    }

    VpSysEnterCritical(deviceId, VP_CODE_CRITICAL_SEC);

    InitLineObject(pLineObj);

    /* Figure out if the line is an FXO or FXS */
    switch (termType) {
        case VP_TERM_FXO_GENERIC:
            if (channelId != 1) {
                VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
                return VP_STATUS_INVALID_ARG;
            }
            pLineObj->status |= VP890_IS_FXO;

            /* FXO is always physical line 1 ([0:1] range). */
            pLineObj->channelId = 1;
            break;

        case VP_TERM_FXS_ISOLATE_LP:
        case VP_TERM_FXS_LOW_PWR:
        case VP_TERM_FXS_SPLITTER_LP:
            pDevObj->stateInt |= (VP890_LINE0_LP | VP890_LINE1_LP);

        case VP_TERM_FXS_GENERIC:
        case VP_TERM_FXS_SPLITTER:
        case VP_TERM_FXS_ISOLATE:
            pLineObj->channelId = channelId;
            pLineObj->status = VP890_INIT_STATUS;
            break;

        default:
            VP_ERROR(VpDevCtxType, pDevCtx, ("Vp890MakeLineObject() - Unsupported termination type"));
            VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);
            return VP_STATUS_ERR_VTD_CODE;
    }

    /* Initialize line context */
    pLineCtx->pLineObj  = pLineObj;
    pLineCtx->pDevCtx   = pDevCtx;

    /* Establish the link between device context to line context */
    pDevCtx->pLineCtx[channelId] = pLineCtx;

    /* Initialize line object */
    pLineObj->termType  = termType;

    /* Note that we are not initializing the 'lineId' member because we do not
     * know what it should be initialized (that information is not provided
     * through the VpMakeLineObj() function) and the basic type of this member
     * is defined by the customer and hence this variable could not have one
     * default value. */

    VpSysExitCritical(deviceId, VP_CODE_CRITICAL_SEC);

    return VP_STATUS_SUCCESS;
}  /* Vp890MakeLineObject() */