From 7ec39f98c1fe4586b486547d6b245e2414306f68 Mon Sep 17 00:00:00 2001 From: Noe Rubinstein Date: Thu, 21 Apr 2011 18:04:43 +0200 Subject: Enable configuration of XHFC w/ GPIOs --- xhfc/base.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file 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, -- cgit v1.2.3