summaryrefslogtreecommitdiff
path: root/xhfc
diff options
context:
space:
mode:
authorGuillaume Knispel <gknispel@proformatique.com>2012-01-06 17:46:58 +0100
committerGuillaume Knispel <gknispel@proformatique.com>2012-01-06 17:46:58 +0100
commitbdd98f7fd0cf16a65acfa0e585433bb4faf0c888 (patch)
treeab280be90937cd30e1c37fc1f363d579c5ccf4b1 /xhfc
parent6838a741f95c7a1d9837eb336fa6ab3f6c283ac9 (diff)
parent5a4adf8c493e33a8f3c7362b67761438facd7280 (diff)
Merge remote branch 'origin/master'
Diffstat (limited to 'xhfc')
-rw-r--r--xhfc/Makefile2
-rw-r--r--xhfc/base.c166
2 files changed, 113 insertions, 55 deletions
diff --git a/xhfc/Makefile b/xhfc/Makefile
index 766d39d..558c296 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) -I$(abspath $(src)/../) -DUSE_GPIO
+CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(abspath $(src)/../) -DUSE_GPIO -DAUDIO
ifeq (1,$(XIVO_AUDIO))
CFLAGS_MODULE += -DAUDIO
diff --git a/xhfc/base.c b/xhfc/base.c
index 42fb14b..0b70dbc 100644
--- a/xhfc/base.c
+++ b/xhfc/base.c
@@ -38,26 +38,61 @@ static int card_cnt = 0;
MODULE_LICENSE("GPL");
-uint debug = 0;
-uint dbg_spanfilter = 0xFFFFFFFF;
-int exit_after_reset = 0;
+#ifdef USE_GPIO
-uint ntte = 0x3;
+#define GPIO_NONE (-1)
-#ifdef USE_GPIO
-static uint reset_gpio = 21;
+int reset_gpio = 21;
+
+int port1_ntte_gpio = GPIO_NONE;
+int port2_ntte_gpio = GPIO_NONE;
+int port3_ntte_gpio = GPIO_NONE;
+int port4_ntte_gpio = GPIO_NONE;
+
+int port1_term_gpio = GPIO_NONE;
+int port2_term_gpio = GPIO_NONE;
+int port3_term_gpio = GPIO_NONE;
+int port4_term_gpio = GPIO_NONE;
+
+module_param(reset_gpio, int, S_IRUGO);
+module_param(port1_ntte_gpio, int, S_IRUGO);
+module_param(port2_ntte_gpio, int, S_IRUGO);
+module_param(port3_ntte_gpio, int, S_IRUGO);
+module_param(port4_ntte_gpio, int, S_IRUGO);
+module_param(port1_term_gpio, int, S_IRUGO);
+module_param(port2_term_gpio, int, S_IRUGO);
+module_param(port3_term_gpio, int, S_IRUGO);
+module_param(port4_term_gpio, int, S_IRUGO);
+
+MODULE_PARM_DESC(reset_gpio, "Reset the XHFC using this GPIO");
+
+MODULE_PARM_DESC(port1_ntte_gpio, "GPIO used for setting port 1 as NT/TE "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port2_ntte_gpio, "GPIO used for setting port 2 as NT/TE "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port3_ntte_gpio, "GPIO used for setting port 3 as NT/TE "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port4_ntte_gpio, "GPIO used for setting port 4 as NT/TE "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port1_term_gpio, "GPIO used for line termination on port 1 "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port2_term_gpio, "GPIO used for line termination on port 2 "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port3_term_gpio, "GPIO used for line termination on port 3 "
+ "(default: -1 = none)");
+MODULE_PARM_DESC(port4_term_gpio, "GPIO used for line termination on port 4 "
+ "(default: -1 = none)");
#endif
-int softconf = 0;
+uint debug = 0;
+uint dbg_spanfilter = 0xFFFFFFFF;
+int exit_after_reset = 0;
+uint ntte = 0x3;
module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(dbg_spanfilter, uint, S_IRUGO | S_IWUSR);
-module_param(softconf, bool, S_IRUGO);
module_param(ntte, uint, S_IRUGO);
module_param(exit_after_reset, bool, S_IRUGO);
-#ifdef USE_GPIO
-module_param(reset_gpio, uint, S_IRUGO);
-#endif
MODULE_PARM_DESC(debug, "Debug bitfield:\n"
"\t0: general\n"
@@ -72,11 +107,6 @@ MODULE_PARM_DESC(debug, "Debug bitfield:\n"
MODULE_PARM_DESC(dbg_spanfilter, "bitfield, filter debug info by span.");
MODULE_PARM_DESC(ntte, "bitfield, configuration of the physical ports. "
"ex: 0x3 = 0 NT, 1 NT, 2 TE, 3 TE.");
-MODULE_PARM_DESC(softconf,
- "Configure the S/T port line interface in software.");
-#ifdef USE_GPIO
-MODULE_PARM_DESC(reset_gpio, "Reset the XHFC using this GPIO");
-#endif
MODULE_PARM_DESC(exit_after_reset, "Exit after hard reset");
void xhfc_waitbusy(struct xhfc *xhfc)
@@ -133,9 +163,9 @@ 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_ctrl2, a_su_wr_sta,
+ 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 =
+ 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);
@@ -148,12 +178,7 @@ void xhfc_config_st(struct xhfc *x, int port, int nt)
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
- * interface is
- * softconfigured, this
- * should always be
- * 0xC XXX */
+ SET_V_SU_CLK_DLY(a_su_clk_dly, 0xC); /* OxE for TE not softconfigured */
SET_V_ST_SMPL(a_su_clk_dly, nt ? 0x6 : 0x0); /* default value */
write_xhfc(x, R_SU_SEL, r_su_sel);
@@ -289,7 +314,7 @@ void xhfc_config_b_chan_on_fifo(struct xhfc *x, int fifo, int slot,
SET_V_CH_SDIR(a_sl_cfg, direction);
SET_V_CH_SNUM(a_sl_cfg, fifo);
- SET_V_ROUT(a_sl_cfg, 3); /* '11': receive data from STIO1,
+ SET_V_ROUT(a_sl_cfg, 3); /* '11': receive data from STIO1,
* output to STIO2 */
write_xhfc(x, R_FIFO, r_fifo);
@@ -330,7 +355,7 @@ static void hdlc_signal_complete(struct xhfc_span *xhfc_span, u8 stat)
printk(KERN_NOTICE DRIVER_NAME "(port %d): STAT=0x%02x "
"indicates frame %d problem: %s\n",
portno(xhfc_span), stat, frames_in,
- (0xff == stat) ?
+ (0xff == stat) ?
"HDLC Abort" : "Bad FCS");
}
@@ -516,9 +541,10 @@ static int hdlc_tx_frame(struct xhfc_span *xhfc_span)
printk(KERN_INFO DRIVER_NAME
": hdlc_tx_frame(span %d): DAHDI gave %d "
- "bytes for FIFO %d (res = %d): %s\n",
- dahdi_span->spanno,
- size, fifo, res, debugbuf);
+ "bytes for FIFO %d (%d frames left; res = %d): "
+ "%s\n", dahdi_span->spanno, size, fifo,
+ atomic_read(&xhfc_span->hdlc_pending),
+ res, debugbuf);
if (size && res != 0)
printk(KERN_INFO DRIVER_NAME
@@ -533,7 +559,7 @@ static int hdlc_tx_frame(struct xhfc_span *xhfc_span)
void xhfc_hdlc_hard_xmit(struct dahdi_chan *chan)
{
struct dahdi_span *dahdi_span = chan->span;
- struct xhfc_span *xhfc_span =
+ struct xhfc_span *xhfc_span =
container_of(dahdi_span, struct xhfc_span, span);
if ((DBG_FOPS || DBG_HDLC) && DBG_SPAN(xhfc_span))
@@ -541,7 +567,7 @@ void xhfc_hdlc_hard_xmit(struct dahdi_chan *chan)
"span=%i (sigchan=%p, chan=%p): %d+1 frames\n",
__func__, chan->name, chan->channo,
chan->chanpos, dahdi_span->spanno,
- xhfc_span->sigchan, chan,
+ xhfc_span->sigchan, chan,
atomic_read(&xhfc_span->hdlc_pending));
/* Increment the hdlc_pending counter and trigger hdlc_tx_frame */
@@ -613,14 +639,14 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs)
}
}
- r_su_irq = read_xhfc(xhfc, R_SU_IRQ);
+ r_su_irq = read_xhfc(xhfc, R_SU_IRQ);
for (i = 0; i < SPANS_PER_CHIP; i++) {
handle_st_timers(&xhfc->spans[i]);
- if (r_su_irq & (1 << i) || 2 == xhfc->ticks /* bootstrap XXX WTF*/)
+ if (r_su_irq & (1 << i))
handle_state_change(&xhfc->spans[i]);
}
- }
+ }
return IRQ_HANDLED;
}
@@ -648,7 +674,8 @@ static void xhfc_rxtx(void *data)
if ((s->span.flags & DAHDI_FLAG_RUNNING) && s->sigchan) { // XXX s->sigchan?
dahdi_receive(&s->span);
- dahdi_transmit(&s->span);
+ if(s->span.alarms == DAHDI_ALARM_NONE)
+ dahdi_transmit(&s->span);
dahdi_ec_span(&s->span);
}
@@ -728,7 +755,7 @@ int xhfc_collect_chip_id(struct xhfc * xhfc)
case CHIP_ID_2SU:
case CHIP_ID_2S4U:
printk(KERN_ERR "%s %s: unsupported device XHFC-%s\n",
- xhfc->name, __func__,
+ xhfc->name, __func__,
chip_id == CHIP_ID_1SU ? "1SU" :
chip_id == CHIP_ID_2SU ? "2SU" :
"2S4U");
@@ -743,6 +770,11 @@ int xhfc_collect_chip_id(struct xhfc * xhfc)
void xhfc_hard_reset(void)
{
#ifdef USE_GPIO
+ if(reset_gpio == GPIO_NONE) {
+ printk(KERN_NOTICE DRIVER_NAME ": No hard reset performed "
+ "(no GPIO configured)\n");
+ return;
+ }
gpio_set_direction(reset_gpio, GPIO_OUTPUT);
gpio_set_to_gpio(reset_gpio);
gpio_set_level(reset_gpio, GPIO_LOW);
@@ -751,17 +783,48 @@ void xhfc_hard_reset(void)
#endif
}
-#if 0
-void configure_port(int port, int nt, int lineterm)
+void configure_ntte(int port, int nt)
{
- gpio_set_direction(lineterm_gpio, GPIO_OUTPUT);
- gpio_set_to_gpio(lineterm_gpio);
- gpio_set_direction(ntte_gpio, GPIO_OUTPUT);
- gpio_set_to_gpio(ntte_gpio);
- gpio_set_level(lineterm_gpio, lineterm);
- gpio_set_level(ntte_gpio, nt);
+ static int *ntte_gpio[] = {
+ &port1_ntte_gpio,
+ &port2_ntte_gpio,
+ &port3_ntte_gpio,
+ &port4_ntte_gpio,
+ };
+
+ if (*ntte_gpio[port] == GPIO_NONE) {
+ printk(KERN_WARNING DRIVER_NAME ": Can't configure "
+ "port %d as %s (no GPIO configured)\n",
+ port + 1, nt ? "NT" : "TE");
+ return;
+ }
+
+ gpio_set_direction(*ntte_gpio[port], GPIO_OUTPUT);
+ gpio_set_to_gpio(*ntte_gpio[port]);
+ gpio_set_level(*ntte_gpio[port], nt);
+}
+
+void configure_term(int port, int lineterm)
+{
+ static int *term_gpio[] = {
+ &port1_term_gpio,
+ &port2_term_gpio,
+ &port3_term_gpio,
+ &port4_term_gpio,
+ };
+
+ if (*term_gpio[port] == GPIO_NONE) {
+ printk(KERN_WARNING DRIVER_NAME ": Can't configure "
+ "line termination on port %d "
+ "(no GPIO configured)\n",
+ port + 1);
+ return;
+ }
+
+ gpio_set_direction(*term_gpio[port], GPIO_OUTPUT);
+ gpio_set_to_gpio(*term_gpio[port]);
+ gpio_set_level(*term_gpio[port], lineterm);
}
-#endif
void xhfc_init_and_configure(struct xhfc* x)
{
@@ -800,22 +863,17 @@ int xhfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc)
/* xref2 */
xhfc_span_set_ntte(xhfc_span, lc->lineconfig & DAHDI_CONFIG_NTTE);
-
term = (lc->lineconfig & DAHDI_CONFIG_TERM) ? 1 : 0;
printk(KERN_INFO DRIVER_NAME ": Configuring port %d span %d in %s mode"
- " with termination resistance %s\n",
+ " with termination resistance %s\n",
portno(xhfc_span), span->spanno,
xhfc_span->nt ? "NT" : "TE",
term ? "ENABLED" : "DISABLED");
- /* TODO conf hardware interface w/ GPIO */
xhfc_config_st(xhfc, xhfc_span->port, xhfc_span->nt);
-
- printk(KERN_INFO DRIVER_NAME ": WARNING: This driver can't configure "
- "the ports yet, expect problems if port %d isn't "
- "configured in %s mode\n",
- portno(xhfc_span), xhfc_span->nt ? "NT" : "TE");
+ configure_ntte(xhfc_span->port, xhfc_span->nt);
+ configure_term(xhfc_span->port, term);
if (lc->sync < 0) {
printk(KERN_INFO DRIVER_NAME
@@ -1240,7 +1298,7 @@ static const struct pci_device_id tlp_leb_pci_tbl[] = {
{ }
};
MODULE_DEVICE_TABLE(pci, tlp_leb_pci_tbl);
-
+
static struct pci_driver xhfc_driver = {
.name = DRIVER_NAME,
.id_table = tlp_leb_pci_tbl,