diff options
author | Guillaume Knispel <gknispel@proformatique.com> | 2012-01-06 17:46:58 +0100 |
---|---|---|
committer | Guillaume Knispel <gknispel@proformatique.com> | 2012-01-06 17:46:58 +0100 |
commit | bdd98f7fd0cf16a65acfa0e585433bb4faf0c888 (patch) | |
tree | ab280be90937cd30e1c37fc1f363d579c5ccf4b1 /xhfc | |
parent | 6838a741f95c7a1d9837eb336fa6ab3f6c283ac9 (diff) | |
parent | 5a4adf8c493e33a8f3c7362b67761438facd7280 (diff) |
Merge remote branch 'origin/master'
Diffstat (limited to 'xhfc')
-rw-r--r-- | xhfc/Makefile | 2 | ||||
-rw-r--r-- | xhfc/base.c | 166 |
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, |