diff options
author | Guillaume Knispel <gknispel@proformatique.com> | 2010-10-17 17:12:23 +0200 |
---|---|---|
committer | Guillaume Knispel <gknispel@proformatique.com> | 2010-10-17 17:12:23 +0200 |
commit | e66c6556b70b871d88ef666f33029b1d27c0c746 (patch) | |
tree | d271e92f4f23b2738ce6714aa30ecae4fe20e2a1 /xhfc | |
parent | 3ffa04249ab3a5abf273e0cc26c4bcc1fc726b4b (diff) |
add some audio for XHFC
Diffstat (limited to 'xhfc')
-rw-r--r-- | xhfc/Makefile | 2 | ||||
-rw-r--r-- | xhfc/xhfc.c | 74 | ||||
-rw-r--r-- | xhfc/xhfc.h | 17 |
3 files changed, 84 insertions, 9 deletions
diff --git a/xhfc/Makefile b/xhfc/Makefile index 6644ad6..62626f1 100644 --- a/xhfc/Makefile +++ b/xhfc/Makefile @@ -2,7 +2,7 @@ PWD := $(shell pwd) KSRC ?= /bad__ksrc__not_set DAHDI_INCLUDE ?= /bad__dahdi_include__not_set -CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -DUSE_GPIO +CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(abspath $(src)/../) -DUSE_GPIO obj-m := xhfcdm.o 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: diff --git a/xhfc/xhfc.h b/xhfc/xhfc.h index 53c99bc..e6f3293 100644 --- a/xhfc/xhfc.h +++ b/xhfc/xhfc.h @@ -4,10 +4,26 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <dahdi/kernel.h> + +#if 1 +# include <tdm/xivo_tdm_api.h> +#else +/* place holder */ +#define ICP_HSSDRV_PORT_XHFC_MEGREZ_PROTO_XIVO_CONFIG 42 +struct xivo_tdm_port { int lol; }; +extern struct xivo_tdm_port kikoolol; +static inline struct xivo_tdm_port* xivo_tdm_get_port(int port) { return &kikoolol; } +static inline void xivo_tdm_put_port(struct xivo_tdm_port* x) {} +static inline int xivo_tdm_config_port(struct xivo_tdm_port* x, unsigned int port_config) { return 0; } +#endif + #include "xhfc24sucd.h" + #define DRIVER_NAME "xhfc" +#define XIVO_XHFC_TDM_PORT 0 + #ifndef CHIP_ID_2S4U #define CHIP_ID_2S4U 0x62 #endif @@ -145,6 +161,7 @@ struct xhfc_pi { struct xhfc xhfc; /* mem for one XHFC */ struct pci_dev *pci_dev; + struct xivo_tdm_port *tdm_port; }; #define dchan_fifo(span) (span->port * 4 + 2) |