summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2011-04-21 18:04:43 +0200
committerNoe Rubinstein <nrubinstein@proformatique.com>2011-04-21 18:04:43 +0200
commit7ec39f98c1fe4586b486547d6b245e2414306f68 (patch)
tree409df2df93bc965b3886482c8a5ebc78013a1736
parent86a30d8e3400f697edb7388603e5ce43e1608471 (diff)
Enable configuration of XHFC w/ GPIOs
-rw-r--r--xhfc/base.c142
1 files changed, 104 insertions, 38 deletions
diff --git a/xhfc/base.c b/xhfc/base.c
index 93b7fe0..4f8d881 100644
--- a/xhfc/base.c
+++ b/xhfc/base.c
@@ -38,23 +38,61 @@ static int card_cnt = 0;
MODULE_LICENSE("GPL");
+#ifdef USE_GPIO
+
+#define GPIO_NONE (-1)
+
+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
+
uint debug = 0;
uint dbg_spanfilter = 0xFFFFFFFF;
int exit_after_reset = 0;
-
uint ntte = 0x3;
-#ifdef USE_GPIO
-static uint reset_gpio = 28;
-#endif
-
module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(dbg_spanfilter, uint, S_IRUGO | S_IWUSR);
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"
@@ -69,9 +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.");
-#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)
@@ -128,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);
@@ -279,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);
@@ -320,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");
}
@@ -523,7 +558,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))
@@ -531,7 +566,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 */
@@ -603,14 +638,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))
handle_state_change(&xhfc->spans[i]);
}
- }
+ }
return IRQ_HANDLED;
}
@@ -718,7 +753,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");
@@ -733,6 +768,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);
@@ -741,17 +781,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)
{
@@ -790,22 +861,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
@@ -1230,7 +1296,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,