summaryrefslogtreecommitdiff
path: root/xhfc
diff options
context:
space:
mode:
authorGuillaume Knispel <gknispel@proformatique.com>2010-10-17 17:12:23 +0200
committerGuillaume Knispel <gknispel@proformatique.com>2010-10-17 17:12:23 +0200
commite66c6556b70b871d88ef666f33029b1d27c0c746 (patch)
treed271e92f4f23b2738ce6714aa30ecae4fe20e2a1 /xhfc
parent3ffa04249ab3a5abf273e0cc26c4bcc1fc726b4b (diff)
add some audio for XHFC
Diffstat (limited to 'xhfc')
-rw-r--r--xhfc/Makefile2
-rw-r--r--xhfc/xhfc.c74
-rw-r--r--xhfc/xhfc.h17
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)