diff options
Diffstat (limited to 'xhfc/xhfc.c')
-rw-r--r-- | xhfc/xhfc.c | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/xhfc/xhfc.c b/xhfc/xhfc.c index e5c6ae1..020f4ff 100644 --- a/xhfc/xhfc.c +++ b/xhfc/xhfc.c @@ -5,7 +5,7 @@ #include <linux/pci.h> #ifdef USE_GPIO -#include "../gpio/gpio.h" +#include <gpio/gpio.h> #endif #include "xhfc24sucd.h" @@ -56,6 +56,9 @@ MODULE_PARM_DESC(reset_gpio, "Reset the XHFC using this GPIO"); #endif MODULE_PARM_DESC(exit_after_reset, "Exit after hard reset"); +#define RX_HISTO_NB 16 +static int rx_histo[RX_HISTO_NB]; + void xhfc_waitbusy(struct xhfc *xhfc) { while (read_xhfc(xhfc, R_STATUS) & M_BUSY) @@ -110,12 +113,16 @@ int xhfc_reset(struct xhfc *xhfc) void xhfc_config_st(struct xhfc *x, int port, int nt) { - u8 r_su_sel, a_su_ctrl0, a_su_ctrl1, a_su_wr_sta, a_su_clk_dly; - r_su_sel = a_su_ctrl0 = a_su_ctrl1 = a_su_wr_sta = a_su_clk_dly = 0x00; + u8 r_su_sel, a_su_ctrl0, a_su_ctrl1, a_su_ctrl2, a_su_wr_sta, a_su_clk_dly; + r_su_sel = a_su_ctrl0 = a_su_ctrl1 = a_su_ctrl2 = a_su_wr_sta = a_su_clk_dly = 0x00; SET_V_SU_SEL(r_su_sel, port); SET_V_SU_MD(a_su_ctrl0, !!nt); + SET_V_B1_TX_EN(a_su_ctrl0, 1); + SET_V_B2_TX_EN(a_su_ctrl0, 1); SET_V_ST_E_IGNO(a_su_ctrl1, nt ? 1 : 0); SET_V_G2_G3_EN(a_su_ctrl1, 1); + SET_V_B1_RX_EN(a_su_ctrl2, 1); + SET_V_B2_RX_EN(a_su_ctrl2, 1); SET_V_SU_ACT(a_su_wr_sta, 3); /* activation */ SET_V_SU_CLK_DLY(a_su_clk_dly, nt ? 0xC : 0xE); /* normal operation * WARNING: if the @@ -127,13 +134,12 @@ void xhfc_config_st(struct xhfc *x, int port, int nt) write_xhfc(x, R_SU_SEL, r_su_sel); xhfc_waitbusy(x); - write_xhfc(x, A_SU_CTRL0, a_su_ctrl0); /* XXX V_B1_TX_EN V_B2_TX_EN */ + write_xhfc(x, A_SU_CTRL0, a_su_ctrl0); write_xhfc(x, A_SU_CTRL1, a_su_ctrl1); + write_xhfc(x, A_SU_CTRL2, a_su_ctrl2); write_xhfc(x, A_SU_CLK_DLY, a_su_clk_dly); write_xhfc(x, A_SU_WR_STA, a_su_wr_sta); xhfc_waitbusy(x); - - /* XXX also in A_SU_CTRL2: V_B1_RX_EN V_B2_RX_EN */ } /* 2 MBit/s (C4IO is 4.096 MHz, 32 time slots): */ @@ -155,7 +161,12 @@ int xhfc_config_pcm(struct xhfc *xhfc, int master_or_slave) write_xhfc(xhfc, R_PCM_MD0, SET_V_PCM_IDX(r_pcm_md0, 0x9)); /* use slow PCM clock adjust speed */ - write_xhfc(xhfc, R_PCM_MD1, M_PLL_ADJ | M_PCM_OD | V_PCM_DR_2M); + write_xhfc(xhfc, R_PCM_MD1, M_PLL_ADJ | V_PCM_DR_2M); + /* NOTE: open drain on the PCM: add bit M_PCM_OD in R_PCM_MD1 + * We can't do that with the demo interface card for + * Megrez <-> XHFC EVB because Xavier did not managed to get + * SMD 1k R before soldering :P + */ if (master_or_slave == XHFC_PCM_MASTER) { write_xhfc(xhfc, R_PCM_MD0, @@ -589,15 +600,34 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) hdlc_rx_frame(s); if (atomic_read(&s->hdlc_pending)) hdlc_tx_frame(s); +#if 1 + /* Put in readchunk chunk _previously_ retrieved + * from icp soft. + * We can't update it at icp level right now, + * because it has been written by trippy monkeys + * and it would probably be a very bad idea to + * try to call it from hardirq context. + * (look at ixOsalMutexLock ... :/ ) + */ + xivo_tdm_receive(pi->tdm_port, i*2 + 0, + s->chans[0]->readchunk); + xivo_tdm_receive(pi->tdm_port, i*2 + 1, + s->chans[1]->readchunk); -#if 0 // Why is this commented out? XXX dahdi_receive(&s->span); dahdi_transmit(&s->span); dahdi_ec_span(&s->span); + + xivo_tdm_transmit(pi->tdm_port, i*2 + 0, + s->chans[0]->writechunk); + xivo_tdm_transmit(pi->tdm_port, i*2 + 1, + s->chans[1]->writechunk); #endif } } + xivo_tdm_tick(pi->tdm_port); + r_su_irq = read_xhfc(xhfc, R_SU_IRQ); for (i = 0; i < ARRAY_SIZE(xhfc->spans); i++) @@ -956,6 +986,11 @@ static struct pci_driver xhfc_driver = { }; +#if 0 /* <stub> */ +struct xivo_tdm_port kikoolol; +#endif /* </stub> */ + + /* pci.txt: called from process context */ int __devinit xhfc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1028,6 +1063,18 @@ int __devinit xhfc_init_one(struct pci_dev *pdev, leb_init(pi); + + /************* + * TDM alloc * + *************/ + + pi->tdm_port = xivo_tdm_get_port(XIVO_XHFC_TDM_PORT); + if (!pi->tdm_port) { + rc = -EBUSY; + goto err_tdm_get_port; + } + + /******************** * XHFC struct init * ********************/ @@ -1072,6 +1119,12 @@ int __devinit xhfc_init_one(struct pci_dev *pdev, init_spans(&pi->xhfc); xhfc_init_and_configure(&pi->xhfc); + /* TDM started on the XHFC side, XHFC is MASTER */ + /* Now it's possible to start the TDM bus on the EP80579 side, as SLAVE: */ + if ((rc = xivo_tdm_config_port(pi->tdm_port, XHFC_MEGREZ_PROTO_XIVO_CONFIG)) < 0) { + printk(KERN_ERR "%s %s: xivo_tdm_config_port failed (err=%d)\n", pi->name, __func__, rc); + goto err_tdm_config_port; + } for (span = 0; span < SPANS_PER_CHIP; span++) if ((rc = dahdi_register(&pi->xhfc.spans[span].span, /*prefmaster*/ 1)) < 0) { @@ -1081,16 +1134,21 @@ int __devinit xhfc_init_one(struct pci_dev *pdev, enable_interrupts(&pi->xhfc); /* enabled in startup <== XXX gnnnnn??? BUGBUG? */ + xivo_tdm_start_chans(pi->tdm_port, /* timeslots 0->7 */ 0xFF); + return 0; err_in_dahdi_register: for (span--; span >= 0; span--) dahdi_unregister(&pi->xhfc.spans[span].span); +err_tdm_config_port: free_irq(pi->irq, pi); err_request_irq: err_collect_chip_id: //acpi_unregister_gsi(IRQ_TLP_GPIO_30); /* symbol doesn't exist??? */ err_acpi_register: + xivo_tdm_put_port(pi->tdm_port); +err_tdm_get_port: exit_after_reset: iounmap(pi->cs_n0); err_ioremap_mmbar: |