cs_status ssp_config_init(ssp_intf_cfg_t *in_cfg) { AHB_SSP_CFG_t cfg; AHB_SSP_CLK_t clk; if (in_cfg == NULL) return CS_E_PARAM; if (0 == in_cfg->speed_kHz) return CS_E_PARAM; CS_REG_READ(IROS_AHB_SSP_CLK, clk.wrd); clk.bf.counter_load = LYNXD_ASIC_HCLK_KHZ/(2*in_cfg->speed_kHz) -1; CS_REG_WRITE(IROS_AHB_SSP_CLK, clk.wrd); SSP_DBG("SSP_CLK: 0x%08x\n", clk.wrd); CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.sel_ssp_cs = 0xF & (1 << in_cfg->ssp_select); cfg.bf.micro_wire_cs_sel = 0xF & (in_cfg->mwr_ssp_select << in_cfg->ssp_select); cfg.bf.tdat_cpha = 0x1 & in_cfg->tdat_cpha; cfg.bf.idat_mode = 0x1 & in_cfg->idat_mode; cfg.bf.datin_cmds = 0x1 & in_cfg->datin_cmds; cfg.bf.edge_align = 0x1 & in_cfg->edge_align; cfg.bf.pre_ssp_dat_cnt = 0x1F & in_cfg->data_len; cfg.bf.ssp_cmd_cnt = 0x7F & in_cfg->command_len; cfg.bf.command_cyc = 0x1 & in_cfg->command_only; CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); SSP_DBG("SSP_CFG: 0x%08x\n", cfg.wrd); return CS_E_OK; }
cs_status ssp_oper_trigger_done(void) { AHB_SSP_CTRL_t ctrl; cs_uint32 cnt = SSP_POLL_TIME; /* start the control to receive the data. * poll until it finishes */ CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); ctrl.bf.sspstart = 1; CS_REG_WRITE(IROS_AHB_SSP_CTRL, ctrl.wrd); do { CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); if (ctrl.bf.sspdone) { break; } } while (cnt--); if (cnt <= 0) { /* unable to receive completely before count runs out */ cs_printf("couldn't complete receiving data\n"); return CS_E_TIMEOUT; } /* write sspdone back to register to clear off */ CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); ctrl.bf.sspdone = 1; CS_REG_WRITE(IROS_AHB_SSP_CTRL, ctrl.wrd); return CS_E_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_drop_cells(cs_uint16 port_id, cs_ctl_t ctl, cs_dir_t dir) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* o CS_RX or CS_TX or CS_TX_AND_RX */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Configures the ATM Cell processor to drop all received cells.*/ /* When CS_ENABLE is set for RX direction, no cells are passed */ /* to the datacom interface. And likewise when DROP is enabled */ /* for the TX direction, no cells are accepted from the datacon */ /* interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; cs_boolean rx_dir , tx_dir ; volatile cs_reg * regaddr ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_FR_PARSE_DIR_CTL(rx_dir, tx_dir, dir) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; if ( rx_dir ) { ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DropCells = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; } if ( tx_dir ) { ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.Drop = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; } ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_tx_clkout(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o TX_CLKOUT control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable/Disable the TX clock output */ /* */ /* Use API arn5_lif_sel_tx_clkout() to select frequency before enable */ /* the output. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.STX_CLKOUT_E = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_tx_clkout(cs_uint16 port_id, arn5_lif_tx_clkout_sel_t sel) /* INPUTS : o Port Id */ /* o Selection, see table below */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select one of the possible clock frequency outputting to TX_CLKOUT */ /* Use with care, no validation. */ /* Use API arn5_lif_ctl_tx_clkout() to enable or disable the selected */ /* output */ /* */ /* [sel] description */ /* ------------------------------------------------------------------ */ /* ARN5_LIF_TX_CLKOUT_STX_CLK stx_clk */ /* ARN5_LIF_TX_CLKOUT_STX_PILOT stx_pilot */ /* ARN5_LIF_TX_CLKOUT_155_MHz (*) 155.52 MHz(SONET)/156.25 MHz(ETH) */ /* ARN5_LIF_TX_CLKOUT_High_Speed high speed clock */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.STX_CLKOUT_SEL = sel & 0x3; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_line_loopback(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o Loopback control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable or disable line loopback at the Line Interface. The */ /* Rx data is looped back to Tx. */ /* User should enable the loop time mode by calling */ /* arn5_lif_ctl_loop_timing API(). */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_GP_CTRL_t gpctrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); gpctrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.GP_CTRL.wrd) ; gpctrl.bf.LINE_LOOP_BK = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.GP_CTRL.wrd, gpctrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return(CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_drop_idle(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable / Disable the filtering of IDLE/unassigned cells . */ /* When Enabled no idle/unassigned cells are passed onto system */ /* interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DropIdle = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_err_correction(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the single bit HEC error correction. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.CorrHec = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_rx_clkout_common(cs_uint16 port_id, arn5_lif_rx_clkout_sel_t sel) /* INPUTS : o Port Id */ /* o Selection, ARN5_LIF_RX_CLKOUT_15X_MHz or */ /* ARN5_LIF_RX_CLKOUT_7X_MHz */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select commonly used clock frequency outputting to RX_CLKOUT */ /* Use API arn5_lif_sel_rx_clkout_raw() for all other selections */ /* Use API arn5_lif_ctl_rx_clkout() to enable or disable the selected */ /* output */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.SRX_CLKOUT_SEL = (sel == ARN5_LIF_RX_CLKOUT_15X_MHz) ? 0x13 : 0x1b; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* Chip select 3 is used for SSP RXD mux, deselect is requred after use*/ void cs3_deselect(void) { AHB_SSP_CFG_t ssp_cfg; /* deselect chip select 3 */ CS_REG_READ(IROS_AHB_SSP_CFG, ssp_cfg.wrd); ssp_cfg.bf.sel_ssp_cs &= 0x7; CS_REG_WRITE(IROS_AHB_SSP_CFG, ssp_cfg.wrd); }
cs_status cs_gpio_intr_disable(cs_uint8 gpio_id) { cs_uint32 val32; CS_REG_READ(CS_GPIO_IE, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_IE,val32); return CS_OK; }
cs_status cs_gpio_read(cs_uint8 gpio_id, cs_uint8* data) { cs_uint32 val32; CS_REG_READ(CS_GPIO_IN, val32); val32 &= (0x1<<gpio_id); *data = (val32?0x1:0x0); return CS_OK; }
cs_status ssp_data_read(cs_int32 *rdata) { AHB_SSP_CFG_t cfg; cs_status ret = CS_E_OK; cs_int32 read_data; /* prepare cfg value */ CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.read_write = 1; /* set it as read */ CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); ret = ssp_oper_trigger_done(); if(CS_E_OK == ret){ /* read the data */ CS_REG_READ(IROS_AHB_SSP_RDAT, read_data); *rdata = read_data; } return ret; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_set_thr_val(cs_uint16 port_id, arn5_framer_atm_thr_t thr, cs_uint8 value) /* INPUTS : o Port Id */ /* o Threshold type */ /* o Threshold value */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Sets the variousthresolds for ATM Cell FSM. */ /* */ /* The [thr] parameter is specified as following: */ /* ARN5_FR_ATM_OOS_THR or ARN5_FR_ATM_IS_THR or */ /* ARN5_FR_ATM_ERR_CORR_THR */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_Cellfsm_t cellFsm ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; if ((thr != ARN5_FR_ATM_ERR_CORR_THR) && (value <= 1)) { CS_HNDL_ERROR( port_id, EARN5_PORT_ID_OUT_OF_RANGE, NULL) ; return (CS_ERROR) ; } ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.Cellfsm.wrd ; cellFsm.wrd = CS_REG_READ(regaddr) ; switch (thr) { case ARN5_FR_ATM_OOS_THR : cellFsm.bf.ALPHA = value ; break ; case ARN5_FR_ATM_IS_THR : cellFsm.bf.DELTA = value ; break ; case ARN5_FR_ATM_ERR_CORR_THR : cellFsm.bf.GAMMA = value ; break ; } CS_REG_WRITE(regaddr, cellFsm.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_hec(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the HEC processing by the ATM Cell processor*/ /* When the HEC check is disabled, cells coming from the datacom*/ /* interface no HEC is inserted. HEC thats coming is passed */ /* along. On RX side, when the check is disabled no HEC checking*/ /* is done and the cells with HEC errors is also passed to */ /* datacom interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.PassHEC = (ctl == CS_DISABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.HECDis = (ctl == CS_DISABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_uint32 arn5_lif_get_prbs_errors(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : PRBS ERROR COUNT */ /* DESCRIPTION: */ /* Gets the current PRBS error count since the time PRBS was enabled. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; cs_uint16 cnt_lsb, cnt_msb ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); cnt_msb = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_CNT_MSB.wrd) ; cnt_lsb = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_CNT_LSB.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return ((cnt_msb << 16) | cnt_lsb) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_scrambling(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the scrambling of the ATM cell payload. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DisDScr = (ctl == CS_ENABLE) ? 0 : 1 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.DisScr = (ctl == CS_ENABLE) ? 0 : 1 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_uint32 arn5_lif_get_status(cs_uint16 port_id, arn5_lif_status_t sel) /* INPUTS : o Port Id */ /* o Status selection */ /* OUTPUTS : ---- */ /* RETURNS : Bitmap status */ /* DESCRIPTION: */ /* Get the current status of the LIF interface. */ /* The [sel] parameter is one of the following: */ /* LIF_PRBS_RX_EFs , LIF_PRBS_SYNCs , LIF_NO_DATAs , */ /* LIF_IN_LOCKs , LIF_SRX_LOCKDETIs , LIF_STATUS_ALL */ /* */ /* LIF_STATUS_ALL : Read the whole status register */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_STATUS_t lif_status ; cs_uint32 status = 0 ; lif_status.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.STATUS.wrd) ; switch ( sel ) { case LIF_PRBS_RX_EFs: status = lif_status.bf.PRBS_RX_EFs ; break ; case LIF_PRBS_SYNCs: status = lif_status.bf.PRBS_SYNCs ; break ; case LIF_NO_DATAs: status = lif_status.bf.NO_DATAs ; break ; case LIF_IN_LOCKs: status = lif_status.bf.IN_LOCKs ; break ; case LIF_SRX_LOCKDETIs: status = lif_status.bf.SRX_LOCKDETIs ; break ; case LIF_STATUS_ALL: status = lif_status.wrd ; break ; } return (status) ; }
cs_status cs_gpio_write(cs_uint8 gpio_id, cs_uint8 data) { cs_uint32 val32; if(g_gpio_mode[gpio_id] == GPIO_OUTPUT) { CS_REG_READ(CS_GPIO_OUT, val32); if(data) val32 |= 0x1<<gpio_id; else val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_OUT,val32); } return CS_OK; }
cs_status ssp_data_write(cs_int32 data) { AHB_SSP_CFG_t cfg; cs_status ret = CS_E_OK; /* prepare cfg value */ CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.read_write = 0; /* set it as write */ CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); CS_REG_WRITE(IROS_AHB_SSP_WDAT, data); ret = ssp_oper_trigger_done(); return ret; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_prbs(cs_uint16 port_id, cs_ctl_t tx_ctl, cs_ctl_t rx_ctl, cs_boolean tx_invert, cs_boolean rx_invert, arn5_lif_prbs_t tx_ptrn, arn5_lif_prbs_t rx_ptrn) /* INPUTS : o Port Id */ /* o CS_DISABLE (default) or CS_ENABLE */ /* o CS_DISABLE (default) or CS_ENABLE */ /* o FALSE or TRUE */ /* o FALSE or TRUE */ /* o TX PRBS pattern */ /* o RX PRBS pattern */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable/Disable the PRBS on LIF interfaces. */ /* */ /* [tx_invert]/[rx_invert] indicates whether to invert the transmit or*/ /* receive PRBS pattern. */ /* */ /* The [tx_ptrn]/[rx_ptrn] parameter is one of the following: */ /* ARN5_LIF_PRBS_PATTERN_31 or ARN5_LIF_PRBS_PATTERN_23 or */ /* ARN5_LIF_PRBS_PATTERN_15 or ARN5_LIF_PRBS_PATTERN_7 */ /* */ /* NOTE : UNFRAMERD PRBS feature can be used for internal/external */ /* loopback diagnostics and SONET compliance test as well. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_PRBS_PROV_t prbs_prvsn ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); prbs_prvsn.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_PROV.wrd) ; prbs_prvsn.bf.PRBS_TX_SEL = tx_ptrn ; prbs_prvsn.bf.PRBS_RX_SEL = rx_ptrn ; prbs_prvsn.bf.PRBS_TX_INVERT = ( tx_invert ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_RX_INVERT = ( rx_invert ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_TX_ENABLE = ( tx_ctl == CS_ENABLE ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_RX_ENABLE = ( rx_ctl == CS_ENABLE ) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_PROV.wrd, prbs_prvsn.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
cs_status cs_gpio_mode_set(cs_uint8 gpio_id, gpio_mode_t mode) { cs_uint32 val32; g_gpio_mode[gpio_id] = mode; switch(mode) { case GPIO_OUTPUT: CS_REG_READ(CS_GPIO_CFG, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_CFG,val32); break; case GPIO_INPUT: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); break; case GPIO_INPUT_FALLING: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); CS_REG_READ(CS_GPIO_LVL, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_LVL,val32); if(!intr_flag) { intr_flag = 0xf; cs_intr_reg(GPIO_INT_NUM, "gpio_irq",cs_gpio_isr, (void*)GPIO_INT_NUM, INTR_DSR_CB); } break; case GPIO_INPUT_RISING: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); CS_REG_READ(CS_GPIO_LVL, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_LVL,val32); if(!intr_flag) { intr_flag = 0xf; cs_intr_reg(GPIO_INT_NUM, "gpio_irq",cs_gpio_isr, (void*)GPIO_INT_NUM, INTR_DSR_CB); } break; } return CS_OK; }
/* CHIP : Arsenal5 */ cs_boolean arn5_lif_is_sreset_done(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : TRUE(reset done) or FALSE(still in reset) */ /* DESCRIPTION: */ /* Returns TRUE if reset of LIF logic is complete or FALSE if */ /* LIF logic is still in reset state. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_RESET_t srst ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); srst.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.RESET.wrd) ; if ( srst.bf.TX_RST || srst.bf.RX_RST ) return (FALSE) ; else return (TRUE) ; }
static cs_status arn5_lif_ctl_clk(ARN5_t * pDev, cs_uint16 sl_num, cs_uint8 clk, cs_ctl_t ctl) { ARN5_LIF_CLOCK_ENABLE_t clkCtrl ; clkCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLOCK_ENABLE.wrd) ; if (clk & ARN5_LIF_RX_CLK) { clkCtrl.bf.RX_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } if (clk & ARN5_LIF_TX_CLK) { clkCtrl.bf.TX_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } if (clk & ARN5_LIF_LD_CLK) { clkCtrl.bf.LD_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLOCK_ENABLE.wrd, clkCtrl.wrd) ; return (CS_OK) ; }
static cs_int32 cs_gpio_isr(int irq, void *dev_id) { cs_uint32 stat; cs_int32 i; if(irq != GPIO_INT_NUM) { cs_printf("lynxd gpio: wrong irq number: %d\n", irq); return CS_ERROR; } CS_REG_READ(CS_GPIO_INT, stat); CS_REG_WRITE(CS_GPIO_INT, stat); for(i=0; i<GPIO_MAX_NUM;i++) { if((stat&(0x1<<i))&& g_gpio_handler[i]!=NULL) g_gpio_handler[i]((void*)g_gpio_handler_data[i]); } return CS_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_analog_loopback(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o Loopback control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable or disable analog terminal loopback at the Line Interface. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_GP_CTRL_t gpctrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); gpctrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.GP_CTRL.wrd) ; gpctrl.bf.FE_TERM_LP_BK = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.GP_CTRL.wrd, gpctrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_rx_clkout_raw(cs_uint16 port_id, cs_uint16 sel) /* INPUTS : o Port Id */ /* o Selection, see table below */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select one of all possible clock frequency outputting to RX_CLKOUT */ /* Use with care, no validation. */ /* Use API arn5_lif_ctl_rx_clkout() to enable or disable the selected */ /* output. */ /* */ /* [sel], the value is mode dependent as listed below. */ /* sel value OC48 mode OC12 mode OC3 mode 1GE mode */ /* -------------------------------------------------------------------*/ /* 0x03 622.08 MHz 622.08 MHz 622.08 MHz 625 MHz */ /* 0x0b 311.04 MHz 311.04 MHz 311.04 MHz 312.5 MHz */ /* 0x13 (*) 155.52 MHz 155.52 MHz 155.52 MHz 156.25 MHz */ /* 0x1b 77.76 MHz 77.76 MHz 77.76 MHz 78.125 MHz */ /* 0x33 38.88 MHz 38.88 MHz 38.88 MHZ 39.0625 MHz */ /* 0x3b SRX_CLK(77.76 MHz) (19.44 MHz) (4.86 MHz) (125 MHz)*/ /* 0x3d 2.488 GHz 2.488 GHz 2.488 GHz 2.5 GHz */ /* 0x3e 2.5 Gb/s 622 Mb/s 155 Mb/s 1.25 Gb/s*/ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.SRX_CLKOUT_SEL = sel; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_init_cfg(cs_uint16 port_id, arn5_port_cfg_t * pPortCfg) /* INPUTS : o Chip Id */ /* o Pointer to port configuration struct */ /* */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* This initializes the port level of the LIF block */ /* with the given summary. */ /* */ /* The [pPortCfg] parameter is a pointer to the configuration */ /* data-structure, which has all the configuration parameters */ /* set. */ /* The API expects the data-structure to be already allocated */ /* and populated with the configuration settings. */ /* $_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; ARN5_LIF_SERDES_CONFIGURATION_t serdes ; cs_uint8 sl_num ; cs_uint32 usec_delay = 100, usec_timeout = 1000 ; cs_uint32 usec_elapsed = 0; arn5_lif_cfg_t * pCfg = &pPortCfg->lif ; //CS_PRINT("\t Initializing LIF... \n") ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF) ; serdes.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.SERDES_CONFIGURATION.wrd) ; serdes.bf.STX_E_CKREF_SEL = (pPortCfg->summ.line_rate == ARN5_PORT_RATE_GIGE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.SERDES_CONFIGURATION.wrd, serdes.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF) ; if (arn5_lif_ctl_rx_clkout(port_id, pCfg->rx_clkout_ctl) != CS_OK) { return CS_ERROR ; } if (arn5_lif_sel_rx_clkout_raw(port_id, pCfg->rx_clkout_sel) != CS_OK) { return CS_ERROR ; } if (arn5_lif_ctl_tx_clkout(port_id, pCfg->tx_clkout_ctl) != CS_OK) { return CS_ERROR ; } if (arn5_lif_sel_tx_clkout(port_id, pCfg->tx_clkout_sel) != CS_OK) { return CS_ERROR ; } if (arn5_lif_ctl_loop_timing(port_id, pCfg->tx_clk_mode) != CS_OK) { return CS_ERROR ; } if (pCfg->terminal_loopback) { if (pCfg->analog_term_lb) { arn5_lif_ctl_analog_loopback(port_id, CS_ENABLE); } else { arn5_lif_ctl_terminal_loopback(port_id, CS_ENABLE); } } else if (pCfg->line_loopback) { arn5_lif_ctl_line_loopback(port_id, CS_ENABLE) ; } /* Soft-reset LIF before starting traffic */ if (arn5_lif_set_sreset(port_id) != CS_OK) { return CS_ERROR ; } while ( !(arn5_lif_is_sreset_done(port_id)) ) { if (usec_elapsed >= usec_timeout) break ; CS_UDELAY(usec_delay) ; usec_elapsed += usec_delay ; } /* Init IRQ Tables and enable default IRQs */ if (arn5_lif_init_irq_cfg(port_id, pCfg) != CS_OK ) { return (CS_ERROR) ; } return(CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_get_running_cfg(cs_uint8 dev_id, arn5_dev_runcfg_t * pRunCfg) /* INPUTS : o Device Id */ /* o Pointer to Device Running Configuration */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Get the current run-time hardware configuration for the */ /* specified device(chip). */ /* */ /* The [pRunCfg] parameter is a pointer to the running */ /* configuration data-structure allocated by the caller. */ /* The driver is responsible for filling in ALL the fields in */ /* the datastructure by reading from HW. */ /* $rtn_hdr_end */ /****************************************************************/ { ARN5_t * pDev ; arn5_dev_cb_t * pdevcb ; arn5_dev_summ_t * pSumm ; cs_uint32 err_code ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return(CS_ERROR) ; } if ( pRunCfg == NULL ) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CFG_NULL, NULL) ; return (CS_ERROR) ; } pDev = ARN5_DEV_ID_TO_DEV_BASE(dev_id) ; pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; CS_MEMSET( (void *)pRunCfg, 0, sizeof(arn5_dev_runcfg_t) ) ; CS_PRINT("ARN5 dev-%d: Retrieving device running configuration..\n", dev_id) ; /* * Get chip's JTAG-Id */ pRunCfg->jtag_id = arn5_get_chip_jtag_id(dev_id) ; /* * Get device summary */ pSumm = &pRunCfg->summ ; pSumm->host_if = ( arn5_spi_dev_is_in_spi42_mode(dev_id) ? ARN5_HOST_IF_SPI42 : ARN5_HOST_IF_SPI3 ) ; /* set block valid flags */ /* GPIO pin configuration */ pRunCfg->gpio.alm_status_map = CS_REG_READ(&pDev->MicroIF.GPIOAlarmControl.wrd) ; pRunCfg->gpio.io_map = ((CS_REG_READ(&pDev->MicroIF.GPIODirection1.wrd) & 0x00ff) << 8) | ((CS_REG_READ(&pDev->MicroIF.GPIODirection0.wrd) & 0x00ff)) ; pRunCfg->gpio.output_values = ((CS_REG_READ(&pDev->MicroIF.GPIOOutput1.wrd) & 0x00ff) << 8) | ((CS_REG_READ(&pDev->MicroIF.GPIOOutput0.wrd) & 0x00ff)) ; /* Block configurations */ if (arn5_spi_dev_get_running_cfg(dev_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_inj_error(cs_uint16 port_id, arn5_lif_prbs_err_t err, cs_boolean once, cs_uint16 duration) /* INPUTS : o Port Id */ /* o ERROR TYPE ( 1 BIT ) OR BLOCK ERROR */ /* o Once ( TRUE ) or continuously ( FALSE ) */ /* o Durtaion of error injection(if doing continously) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Injects error in the PRBS stream. */ /* The [err] parameter is one of the following: */ /* ARN5_LIF_PRBS_1_BIT_ERR or ARN5_LIF_PRBS_BLOCK_ERR */ /* Note : This function might block for "duration" if continuous */ /* errors need to be generated. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_PRBS_CTRL_t prbsCtrl ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); prbsCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd) ; ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); switch ( err ) { case ARN5_LIF_PRBS_BLOCK_ERR: if(once) { prbsCtrl.bf.PRBS_WORD_ERR_INJ_ONCE = 1 ; } else { prbsCtrl.bf.PRBS_WORD_ERR_INJ = 1 ; } break ; case ARN5_LIF_PRBS_1_BIT_ERR: if(once) { prbsCtrl.bf.PRBS_BIT_ERR_INJ_ONCE = 1 ; } else { prbsCtrl.bf.PRBS_BIT_ERR_INJ = 1 ; } break ; default : ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); CS_HNDL_ERROR(port_id, EARN5_LIF_INVALID_ERROR_OP, "\n" ) ; return (CS_ERROR) ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd, prbsCtrl.wrd) ; if(!once) { CS_UDELAY(duration) ; if ( err == ARN5_LIF_PRBS_BLOCK_ERR ) { prbsCtrl.bf.PRBS_WORD_ERR_INJ = 0 ; } else { prbsCtrl.bf.PRBS_BIT_ERR_INJ = 0 ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd, prbsCtrl.wrd) ; } ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }