diff options
Diffstat (limited to 'drivers/dahdi/wctdm24xxp/base.c')
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 1293 |
1 files changed, 743 insertions, 550 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index a828328..58efb7d 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -107,10 +107,9 @@ static int loopcurrent = 20; * polarity reversal for the port, * and the state of the line reversal MWI indicator */ -#define POLARITY_XOR(card) \ - ((reversepolarity != 0) ^ \ - (wc->mods[(card)].mod.fxs.reversepolarity != 0) ^ \ - (wc->mods[(card)].mod.fxs.vmwi_linereverse != 0)) +#define POLARITY_XOR(fxs) \ + ((reversepolarity != 0) ^ ((fxs)->reversepolarity != 0) ^ \ + ((fxs)->vmwi_linereverse != 0)) static int reversepolarity = 0; @@ -259,7 +258,9 @@ static const struct dahdi_echocan_ops vpm_ec_ops = { .echocan_free = echocan_free, }; -static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane); +static int +wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod, int fast, + int manual, int sane); static inline int CMD_BYTE(int card, int bit, int altcs) { @@ -278,11 +279,11 @@ static inline int CMD_BYTE(int card, int bit, int altcs) + ((card) >> 2) + (altcs) + ((altcs) ? -21 : 0)); } -static inline int empty_slot(struct wctdm *wc, int card) +static inline int empty_slot(struct wctdm_module *const mod) { int x; for (x = 0; x < USER_COMMANDS; x++) { - if (!wc->mods[card].cmdq.cmds[x]) + if (!mod->cmdq.cmds[x]) return x; } return -1; @@ -424,11 +425,12 @@ static int config_vpmadt032(struct vpmadt032 *vpm, struct wctdm *wc) } for (i = 0; i < vpm->options.channels; ++i) { + struct dahdi_chan *const chan = &wc->mods[i].chan->chan; vpm->curecstate[i].tap_length = 0; vpm->curecstate[i].nlp_type = vpm->options.vpmnlptype; vpm->curecstate[i].nlp_threshold = vpm->options.vpmnlpthresh; vpm->curecstate[i].nlp_max_suppress = vpm->options.vpmnlpmaxsupp; - vpm->curecstate[i].companding = (wc->chans[i]->chan.span->deflaw == DAHDI_LAW_ALAW) ? ADT_COMP_ALAW : ADT_COMP_ULAW; + vpm->curecstate[i].companding = (chan->span->deflaw == DAHDI_LAW_ALAW) ? ADT_COMP_ALAW : ADT_COMP_ULAW; /* set_vpmadt032_chanconfig_from_state(&vpm->curecstate[i], &vpm->options, i, &chanconfig); !!! */ vpm->setchanconfig_from_state(vpm, i, &chanconfig); if ((res = gpakConfigureChannel(vpm->dspid, i, tdmToTdm, &chanconfig, &cstatus))) { @@ -768,10 +770,8 @@ static inline void cmd_decipher(struct wctdm *wc, const u8 *eframe, int card) spin_unlock_irqrestore(&wc->reglock, flags); } -static inline void cmd_checkisr(struct wctdm *wc, int card) +static void cmd_checkisr(struct wctdm *wc, struct wctdm_module *const mod) { - struct wctdm_module *const mod = &wc->mods[card]; - if (!mod->cmdq.cmds[USER_COMMANDS + 0]) { if (mod->sethook) { mod->cmdq.cmds[USER_COMMANDS + 0] = mod->sethook; @@ -781,9 +781,9 @@ static inline void cmd_checkisr(struct wctdm *wc, int card) } else if (mod->type == FXO) { mod->cmdq.cmds[USER_COMMANDS + 0] = CMD_RD(5); /* Hook/Ring state */ } else if (mod->type == QRV) { - wc->mods[card & 0xfc].cmdq.cmds[USER_COMMANDS + 0] = CMD_RD(3); /* COR/CTCSS state */ + wc->mods[mod->card & 0xfc].cmdq.cmds[USER_COMMANDS + 0] = CMD_RD(3); /* COR/CTCSS state */ } else if (mod->type == BRI) { - mod->cmdq.cmds[USER_COMMANDS + 0] = wctdm_bri_checkisr(wc, card, 0); + wctdm_bri_checkisr(wc, mod, 0); } } if (!mod->cmdq.cmds[USER_COMMANDS + 1]) { @@ -796,9 +796,9 @@ static inline void cmd_checkisr(struct wctdm *wc, int card) } else if (mod->type == FXO) { mod->cmdq.cmds[USER_COMMANDS + 1] = CMD_RD(29); /* Battery */ } else if (mod->type == QRV) { - wc->mods[card & 0xfc].cmdq.cmds[USER_COMMANDS + 1] = CMD_RD(3); /* Battery */ + wc->mods[mod->card & 0xfc].cmdq.cmds[USER_COMMANDS + 1] = CMD_RD(3); /* Battery */ } else if (mod->type == BRI) { - mod->cmdq.cmds[USER_COMMANDS + 1] = wctdm_bri_checkisr(wc, card, 1); + wctdm_bri_checkisr(wc, mod, 1); } } } @@ -813,7 +813,7 @@ static void insert_tdm_data(const struct wctdm *wc, u8 *sframe) register u8 *chanchunk; for (i = 0; i < wc->avchannels; i += 4) { - chanchunk = &wc->chans[0 + i]->chan.writechunk[0]; + chanchunk = &wc->mods[0 + i].chan->chan.writechunk[0]; sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*0] = chanchunk[0]; sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*1] = chanchunk[1]; sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*2] = chanchunk[2]; @@ -823,7 +823,7 @@ static void insert_tdm_data(const struct wctdm *wc, u8 *sframe) sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*6] = chanchunk[6]; sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*7] = chanchunk[7]; - chanchunk = &wc->chans[1 + i]->chan.writechunk[0]; + chanchunk = &wc->mods[1 + i].chan->chan.writechunk[0]; sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*0] = chanchunk[0]; sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*1] = chanchunk[1]; sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*2] = chanchunk[2]; @@ -833,7 +833,7 @@ static void insert_tdm_data(const struct wctdm *wc, u8 *sframe) sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*6] = chanchunk[6]; sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*7] = chanchunk[7]; - chanchunk = &wc->chans[2 + i]->chan.writechunk[0]; + chanchunk = &wc->mods[2 + i].chan->chan.writechunk[0]; sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*0] = chanchunk[0]; sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*1] = chanchunk[1]; sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*2] = chanchunk[2]; @@ -843,7 +843,7 @@ static void insert_tdm_data(const struct wctdm *wc, u8 *sframe) sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*6] = chanchunk[6]; sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*7] = chanchunk[7]; - chanchunk = &wc->chans[3 + i]->chan.writechunk[0]; + chanchunk = &wc->mods[3 + i].chan->chan.writechunk[0]; sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*0] = chanchunk[0]; sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*1] = chanchunk[1]; sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*2] = chanchunk[2]; @@ -888,7 +888,7 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *sframe) * installed modules. */ for (y = 0; y < wc->avchannels; y++) { if (!x && y < wc->mods_per_board) { - cmd_checkisr(wc, y); + cmd_checkisr(wc, &wc->mods[y]); } if (y < wc->mods_per_board) @@ -912,55 +912,59 @@ static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *sframe) } static bool -stuff_command(struct wctdm *wc, int card, unsigned int cmd, int *hit) +stuff_command(struct wctdm *wc, struct wctdm_module *const mod, + unsigned int cmd, int *hit) { unsigned long flags; spin_lock_irqsave(&wc->reglock, flags); - *hit = empty_slot(wc, card); + *hit = empty_slot(mod); if (*hit > -1) - wc->mods[card].cmdq.cmds[*hit] = cmd; + mod->cmdq.cmds[*hit] = cmd; spin_unlock_irqrestore(&wc->reglock, flags); return (*hit > -1); } static int -wctdm_setreg_full(struct wctdm *wc, int card, int addr, int val, int inisr) +wctdm_setreg_full(struct wctdm *wc, struct wctdm_module *mod, + int addr, int val, int inisr) { + const unsigned int cmd = CMD_WR(addr, val); int ret; int hit; - const unsigned int cmd = CMD_WR(addr, val); +#if 0 /* TODO */ /* QRV and BRI cards are only addressed at their first "port" */ if ((card & 0x03) && ((wc->mods[card].type == QRV) || (wc->mods[card].type == BRI))) return 0; +#endif if (inisr) { - stuff_command(wc, card, cmd, &hit); + stuff_command(wc, mod, cmd, &hit); return 0; } ret = wait_event_interruptible(wc->regq, - stuff_command(wc, card, cmd, &hit)); + stuff_command(wc, mod, cmd, &hit)); return ret; } static inline void -wctdm_setreg_intr(struct wctdm *wc, int card, int addr, int val) +wctdm_setreg_intr(struct wctdm *wc, struct wctdm_module *mod, int addr, int val) { - wctdm_setreg_full(wc, card, addr, val, 1); + wctdm_setreg_full(wc, mod, addr, val, 1); } -int wctdm_setreg(struct wctdm *wc, int card, int addr, int val) +int wctdm_setreg(struct wctdm *wc, struct wctdm_module *mod, int addr, int val) { - return wctdm_setreg_full(wc, card, addr, val, 0); + return wctdm_setreg_full(wc, mod, addr, val, 0); } -static bool cmd_finished(struct wctdm *wc, int card, int hit, u8 *val) +static bool +cmd_finished(struct wctdm *wc, struct wctdm_module *const mod, int hit, u8 *val) { - struct wctdm_module *const mod = &wc->mods[card]; bool ret; unsigned long flags; @@ -977,26 +981,28 @@ static bool cmd_finished(struct wctdm *wc, int card, int hit, u8 *val) return ret; } -int wctdm_getreg(struct wctdm *wc, int card, int addr) +int wctdm_getreg(struct wctdm *wc, struct wctdm_module *const mod, int addr) { const unsigned int cmd = CMD_RD(addr); u8 val = 0; int hit; int ret; +#if 0 /* TODO */ /* if a QRV card, use only its first channel */ if (wc->mods[card].type == QRV) { if (card & 3) return 0; } +#endif ret = wait_event_interruptible(wc->regq, - stuff_command(wc, card, cmd, &hit)); + stuff_command(wc, mod, cmd, &hit)); if (ret) return ret; ret = wait_event_interruptible(wc->regq, - cmd_finished(wc, card, hit, &val)); + cmd_finished(wc, mod, hit, &val)); if (ret) return ret; @@ -1035,7 +1041,7 @@ static void extract_tdm_data(struct wctdm *wc, const u8 *sframe) register u8 *chanchunk; for (i = 0; i < wc->avchannels; i += 4) { - chanchunk = &wc->chans[0 + i]->chan.readchunk[0]; + chanchunk = &wc->mods[0 + i].chan->chan.readchunk[0]; chanchunk[0] = sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*0]; chanchunk[1] = sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*1]; chanchunk[2] = sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*2]; @@ -1045,7 +1051,7 @@ static void extract_tdm_data(struct wctdm *wc, const u8 *sframe) chanchunk[6] = sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*6]; chanchunk[7] = sframe[0 + i + (EFRAME_SIZE + EFRAME_GAP)*7]; - chanchunk = &wc->chans[1 + i]->chan.readchunk[0]; + chanchunk = &wc->mods[1 + i].chan->chan.readchunk[0]; chanchunk[0] = sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*0]; chanchunk[1] = sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*1]; chanchunk[2] = sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*2]; @@ -1055,7 +1061,7 @@ static void extract_tdm_data(struct wctdm *wc, const u8 *sframe) chanchunk[6] = sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*6]; chanchunk[7] = sframe[1 + i + (EFRAME_SIZE + EFRAME_GAP)*7]; - chanchunk = &wc->chans[2 + i]->chan.readchunk[0]; + chanchunk = &wc->mods[2 + i].chan->chan.readchunk[0]; chanchunk[0] = sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*0]; chanchunk[1] = sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*1]; chanchunk[2] = sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*2]; @@ -1065,7 +1071,7 @@ static void extract_tdm_data(struct wctdm *wc, const u8 *sframe) chanchunk[6] = sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*6]; chanchunk[7] = sframe[2 + i + (EFRAME_SIZE + EFRAME_GAP)*7]; - chanchunk = &wc->chans[3 + i]->chan.readchunk[0]; + chanchunk = &wc->mods[3 + i].chan->chan.readchunk[0]; chanchunk[0] = sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*0]; chanchunk[1] = sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*1]; chanchunk[2] = sframe[3 + i + (EFRAME_SIZE + EFRAME_GAP)*2]; @@ -1115,7 +1121,7 @@ static inline void wctdm_receiveprep(struct wctdm *wc, const u8 *sframe) /* XXX We're wasting 8 taps. We should get closer :( */ if (likely(wc->initialized)) { for (x = 0; x < wc->avchannels; x++) { - struct dahdi_chan *c = &wc->chans[x]->chan; + struct dahdi_chan *c = &wc->mods[x].chan->chan; #ifdef CONFIG_VOICEBUS_ECREFERENCE unsigned char buffer[DAHDI_CHUNKSIZE]; __dahdi_fifo_get(wc->ec_reference[x], buffer, @@ -1149,26 +1155,24 @@ static inline void wctdm_receiveprep(struct wctdm *wc, const u8 *sframe) wake_up_interruptible_all(&wc->regq); } -static int wait_access(struct wctdm *wc, int card) +static int wait_access(struct wctdm *wc, struct wctdm_module *const mod) { - unsigned char data=0; - int count = 0; - - #define MAX 10 /* attempts */ - + unsigned char data = 0; + int count = 0; - /* Wait for indirect access */ - while (count++ < MAX) - { - data = wctdm_getreg(wc, card, I_STATUS); + #define MAX 10 /* attempts */ + /* Wait for indirect access */ + while (count++ < MAX) { + data = wctdm_getreg(wc, mod, I_STATUS); if (!data) return 0; + } - } - - if (count > (MAX-1)) - dev_notice(&wc->vb.pdev->dev, " ##### Loop error (%02x) #####\n", data); + if (count > (MAX-1)) { + dev_notice(&wc->vb.pdev->dev, + " ##### Loop error (%02x) #####\n", data); + } return 0; } @@ -1185,40 +1189,44 @@ static unsigned char translate_3215(unsigned char address) return address; } -static int wctdm_proslic_setreg_indirect(struct wctdm *wc, int card, unsigned char address, unsigned short data) +static int +wctdm_proslic_setreg_indirect(struct wctdm *wc, struct wctdm_module *const mod, + unsigned char address, unsigned short data) { int res = -1; /* Translate 3215 addresses */ - if (wc->mods[card].flags & FLAG_3215) { + if (mod->flags & FLAG_3215) { address = translate_3215(address); if (address == 255) return 0; } - if (!wait_access(wc, card)) { - wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF)); - wctdm_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8)); - wctdm_setreg(wc, card, IAA,address); + if (!wait_access(wc, mod)) { + wctdm_setreg(wc, mod, IDA_LO, (u8)(data & 0xFF)); + wctdm_setreg(wc, mod, IDA_HI, (u8)((data & 0xFF00)>>8)); + wctdm_setreg(wc, mod, IAA, address); res = 0; }; return res; } -static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned char address) +static int +wctdm_proslic_getreg_indirect(struct wctdm *wc, struct wctdm_module *const mod, + unsigned char address) { int res = -1; char *p=NULL; /* Translate 3215 addresses */ - if (wc->mods[card].flags & FLAG_3215) { + if (mod->flags & FLAG_3215) { address = translate_3215(address); if (address == 255) return 0; } - if (!wait_access(wc, card)) { - wctdm_setreg(wc, card, IAA, address); - if (!wait_access(wc, card)) { + if (!wait_access(wc, mod)) { + wctdm_setreg(wc, mod, IAA, address); + if (!wait_access(wc, mod)) { unsigned char data1, data2; - data1 = wctdm_getreg(wc, card, IDA_LO); - data2 = wctdm_getreg(wc, card, IDA_HI); + data1 = wctdm_getreg(wc, mod, IDA_LO); + data2 = wctdm_getreg(wc, mod, IDA_HI); res = data1 | (data2 << 8); } else p = "Failed to wait inside\n"; @@ -1229,12 +1237,13 @@ static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned ch return res; } -static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card) +static int +wctdm_proslic_init_indirect_regs(struct wctdm *wc, struct wctdm_module *mod) { unsigned char i; for (i = 0; i < ARRAY_SIZE(indirect_regs); i++) { - if (wctdm_proslic_setreg_indirect(wc, card, + if (wctdm_proslic_setreg_indirect(wc, mod, indirect_regs[i].address, indirect_regs[i].initial)) return -1; @@ -1243,22 +1252,23 @@ static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card) return 0; } -static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card) +static int +wctdm_proslic_verify_indirect_regs(struct wctdm *wc, struct wctdm_module *mod) { int passed = 1; unsigned short i, initial; int j; - for (i = 0; i < ARRAY_SIZE(indirect_regs); i++) - { - j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address); + for (i = 0; i < ARRAY_SIZE(indirect_regs); i++) { + j = wctdm_proslic_getreg_indirect(wc, mod, + (u8)indirect_regs[i].address); if (j < 0) { dev_notice(&wc->vb.pdev->dev, "Failed to read indirect register %d\n", i); return -1; } - initial= indirect_regs[i].initial; + initial = indirect_regs[i].initial; - if ((j != initial) && (!(wc->mods[card].flags & FLAG_3215) || + if ((j != initial) && (!(mod->flags & FLAG_3215) || (indirect_regs[i].altaddr != 255))) { dev_notice(&wc->vb.pdev->dev, "!!!!!!! %s iREG %X = %X should be %X\n", @@ -1268,20 +1278,23 @@ static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card) } } - if (passed) { - if (debug & DEBUG_CARD) - dev_info(&wc->vb.pdev->dev, "Init Indirect Registers completed successfully.\n"); - } else { - dev_notice(&wc->vb.pdev->dev, " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n"); + if (passed) { + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "Init Indirect Registers completed successfully.\n"); + } + } else { + dev_notice(&wc->vb.pdev->dev, + " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n"); return -1; - } - return 0; + } + return 0; } /* 1ms interrupt */ -static inline void wctdm_proslic_check_oppending(struct wctdm *wc, int card) +static void +wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod) { - struct wctdm_module *const mod = &wc->mods[card]; struct fxs *const fxs = &mod->mod.fxs; int res; @@ -1303,7 +1316,7 @@ static inline void wctdm_proslic_check_oppending(struct wctdm *wc, int card) if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "SLIC_LF OK: card=%d shadow=%02x " - "lasttxhook=%02x intcount=%d\n", card, + "lasttxhook=%02x intcount=%d\n", mod->card, res, fxs->lasttxhook, wc->intcount); } } else if (fxs->oppending_ms && (--fxs->oppending_ms == 0)) { @@ -1312,7 +1325,7 @@ static inline void wctdm_proslic_check_oppending(struct wctdm *wc, int card) if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "SLIC_LF RETRY: card=%d shadow=%02x " - "lasttxhook=%02x intcount=%d\n", card, + "lasttxhook=%02x intcount=%d\n", mod->card, res, fxs->lasttxhook, wc->intcount); } } else { /* Start 100ms Timeout */ @@ -1322,9 +1335,9 @@ static inline void wctdm_proslic_check_oppending(struct wctdm *wc, int card) } /* 256ms interrupt */ -static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card) +static void +wctdm_proslic_recheck_sanity(struct wctdm *wc, struct wctdm_module *const mod) { - struct wctdm_module *const mod = &wc->mods[card]; struct fxs *const fxs = &mod->mod.fxs; int res; unsigned long flags; @@ -1378,10 +1391,12 @@ static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card) if (res) { fxs->palarms++; if (fxs->palarms < MAX_ALARMS) { - dev_notice(&wc->vb.pdev->dev, "Power alarm on module %d, resetting!\n", card + 1); + dev_notice(&wc->vb.pdev->dev, + "Power alarm on module %d, resetting!\n", + mod->card + 1); spin_lock_irqsave(&fxs->lasttxhooklock, flags); if (fxs->lasttxhook == SLIC_LF_RINGING) { - fxs->lasttxhook = POLARITY_XOR(card) ? + fxs->lasttxhook = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD;; } @@ -1392,14 +1407,17 @@ static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card) /* Update shadow register to avoid extra power alarms until next read */ mod->cmdq.isrshadow[1] = fxs->lasttxhook; } else { - if (fxs->palarms == MAX_ALARMS) - dev_notice(&wc->vb.pdev->dev, "Too many power alarms on card %d, NOT resetting!\n", card + 1); + if (fxs->palarms == MAX_ALARMS) { + dev_notice(&wc->vb.pdev->dev, + "Too many power alarms on card %d, " + "NOT resetting!\n", mod->card + 1); + } } } #endif } -static inline void wctdm_qrvdri_check_hook(struct wctdm *wc, int card) +static void wctdm_qrvdri_check_hook(struct wctdm *wc, int card) { signed char b,b1; int qrvcard = card & 0xfc; @@ -1467,14 +1485,14 @@ static inline void wctdm_qrvdri_check_hook(struct wctdm *wc, int card) return; } -static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) +static void +wctdm_voicedaa_check_hook(struct wctdm *wc, struct wctdm_module *const mod) { #define MS_PER_CHECK_HOOK 1 unsigned char res; signed char b; unsigned int abs_voltage; - struct wctdm_module *const mod = &wc->mods[card]; struct fxo *const fxo = &mod->mod.fxo; /* Try to track issues that plague slot one FXO's */ @@ -1482,10 +1500,10 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) b &= 0x9b; if (fxo->offhook) { if (b != 0x9) - wctdm_setreg_intr(wc, card, 5, 0x9); + wctdm_setreg_intr(wc, mod, 5, 0x9); } else { if (b != 0x8) - wctdm_setreg_intr(wc, card, 5, 0x8); + wctdm_setreg_intr(wc, mod, 5, 0x8); } if (!fxo->offhook) { if (fwringdetect || neonmwi_monitor) { @@ -1514,8 +1532,8 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (++fxo->lastrdtx_count >= 2) { fxo->wasringing = 1; if (debug) - dev_info(&wc->vb.pdev->dev, "FW RING on %d/%d!\n", wc->aspan->span.spanno, card + 1); - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_RING); + dev_info(&wc->vb.pdev->dev, "FW RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_RING); fxo->ringdebounce = ringdebounce / 16; } else { fxo->lastrdtx = res; @@ -1531,8 +1549,8 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) } else if (--fxo->ringdebounce == 0) { fxo->wasringing = 0; if (debug) - dev_info(&wc->vb.pdev->dev, "FW NO RING on %d/%d!\n", wc->aspan->span.spanno, card + 1); - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_OFFHOOK); + dev_info(&wc->vb.pdev->dev, "FW NO RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK); } } } else { @@ -1542,9 +1560,9 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) { if (!fxo->wasringing) { fxo->wasringing = 1; - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_RING); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_RING); if (debug) - dev_info(&wc->vb.pdev->dev, "RING on %d/%d!\n", wc->aspan->span.spanno, card + 1); + dev_info(&wc->vb.pdev->dev, "RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1); } fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce; } @@ -1553,9 +1571,9 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (fxo->ringdebounce <= 0) { if (fxo->wasringing) { fxo->wasringing = 0; - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_OFFHOOK); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK); if (debug) - dev_info(&wc->vb.pdev->dev, "NO RING on %d/%d!\n", wc->aspan->span.spanno, card + 1); + dev_info(&wc->vb.pdev->dev, "NO RING on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1); } fxo->ringdebounce = 0; } @@ -1569,11 +1587,11 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (fxovoltage) { if (!(wc->intcount % 100)) { - dev_info(&wc->vb.pdev->dev, "Port %d: Voltage: %d Debounce %d\n", card + 1, b, fxo->battdebounce); + dev_info(&wc->vb.pdev->dev, "Port %d: Voltage: %d Debounce %d\n", mod->card + 1, b, fxo->battdebounce); } } - if (unlikely(DAHDI_RXSIG_INITIAL == wc->aspan->span.chans[card]->rxhooksig)) { + if (unlikely(DAHDI_RXSIG_INITIAL == mod->chan->chan.rxhooksig)) { /* * dahdi-base will set DAHDI_RXSIG_INITIAL after a * DAHDI_STARTUP or DAHDI_CHANCONFIG ioctl so that new events @@ -1608,7 +1626,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (--fxo->battdebounce == 0) { fxo->battery = BATTERY_LOST; if (debug) - dev_info(&wc->vb.pdev->dev, "NO BATTERY on %d/%d!\n", wc->aspan->span.spanno, card + 1); + dev_info(&wc->vb.pdev->dev, "NO BATTERY on %d/%d!\n", wc->aspan->span.spanno, mod->card + 1); #ifdef JAPAN if (!wc->ohdebounce && wc->offhook) { dahdi_hooksig(wc->aspan->chans[card], DAHDI_RXSIG_ONHOOK); @@ -1619,7 +1637,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) #endif } #else - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_ONHOOK); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_ONHOOK); /* set the alarm timer, taking into account that part of its time period has already passed while debouncing occurred */ fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK; @@ -1653,7 +1671,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) dev_info(&wc->vb.pdev->dev, "BATTERY on %d/%d (%s)!\n", wc->aspan->span.spanno, - card + 1, + mod->card + 1, (b < 0) ? "-" : "+"); } #ifdef ZERO_BATT_RING @@ -1664,7 +1682,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) dev_info(&wc->vb.pdev->dev, "Signalled Off Hook\n"); } #else - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_OFFHOOK); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK); #endif /* set the alarm timer, taking into account that part of its time period has already passed while debouncing occurred */ @@ -1694,7 +1712,10 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (--fxo->battalarm == 0) { /* the alarm timer has expired, so update the battery alarm state for this channel */ - dahdi_alarm_channel(wc->aspan->span.chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE); + dahdi_alarm_channel(&mod->chan->chan, + (fxo->battery == BATTERY_LOST) ? + DAHDI_ALARM_RED : + DAHDI_ALARM_NONE); } } @@ -1707,7 +1728,7 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) fxo->polarity, fxo->lastpol); if (fxo->polarity) - dahdi_qevent_lock(wc->aspan->span.chans[card], DAHDI_EVENT_POLARITY); + dahdi_qevent_lock(&mod->chan->chan, DAHDI_EVENT_POLARITY); fxo->polarity = fxo->lastpol; } } @@ -1727,10 +1748,10 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (NEONMWI_ON_DEBOUNCE == fxo->neonmwi_debounce) { fxo->neonmwi_offcounter = neonmwi_offlimit_cycles; if (0 == fxo->neonmwi_state) { - dahdi_qevent_lock(wc->aspan->span.chans[card], DAHDI_EVENT_NEONMWI_ACTIVE); + dahdi_qevent_lock(&mod->chan->chan, DAHDI_EVENT_NEONMWI_ACTIVE); fxo->neonmwi_state = 1; if (debug) - dev_info(&wc->vb.pdev->dev, "NEON MWI active for card %d\n", card+1); + dev_info(&wc->vb.pdev->dev, "NEON MWI active for card %d\n", mod->card+1); } fxo->neonmwi_debounce++; /* terminate the processing */ } else if (NEONMWI_ON_DEBOUNCE > fxo->neonmwi_debounce) { @@ -1746,41 +1767,44 @@ static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card) if (fxo->neonmwi_state && 0 < fxo->neonmwi_offcounter ) { fxo->neonmwi_offcounter--; if (0 == fxo->neonmwi_offcounter) { - dahdi_qevent_lock(wc->aspan->span.chans[card], DAHDI_EVENT_NEONMWI_INACTIVE); + dahdi_qevent_lock(&mod->chan->chan, DAHDI_EVENT_NEONMWI_INACTIVE); fxo->neonmwi_state = 0; if (debug) - dev_info(&wc->vb.pdev->dev, "NEON MWI cleared for card %d\n", card+1); + dev_info(&wc->vb.pdev->dev, "NEON MWI cleared for card %d\n", mod->card+1); } } } #undef MS_PER_CHECK_HOOK } -static void wctdm_fxs_hooksig(struct wctdm *wc, const int card, enum dahdi_txsig txsig) +static void +wctdm_fxs_hooksig(struct wctdm *wc, struct wctdm_module *const mod, + enum dahdi_txsig txsig) { int x = 0; unsigned long flags; - struct fxs *const fxs = &wc->mods[card].mod.fxs; + struct fxs *const fxs = &mod->mod.fxs; + spin_lock_irqsave(&fxs->lasttxhooklock, flags); switch (txsig) { case DAHDI_TXSIG_ONHOOK: - switch (wc->aspan->span.chans[card]->sig) { + switch (mod->chan->chan.sig) { case DAHDI_SIG_EM: case DAHDI_SIG_FXOKS: case DAHDI_SIG_FXOLS: x = fxs->idletxhookstate; break; case DAHDI_SIG_FXOGS: - x = (POLARITY_XOR(card)) ? + x = (POLARITY_XOR(fxs)) ? SLIC_LF_RING_OPEN : SLIC_LF_TIP_OPEN; break; } break; case DAHDI_TXSIG_OFFHOOK: - switch (wc->aspan->span.chans[card]->sig) { + switch (mod->chan->chan.sig) { case DAHDI_SIG_EM: - x = (POLARITY_XOR(card)) ? + x = (POLARITY_XOR(fxs)) ? SLIC_LF_ACTIVE_FWD : SLIC_LF_ACTIVE_REV; break; @@ -1804,7 +1828,7 @@ static void wctdm_fxs_hooksig(struct wctdm *wc, const int card, enum dahdi_txsig if (x != fxs->lasttxhook) { fxs->lasttxhook = x | SLIC_LF_OPPENDING; - wc->mods[card].sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); + mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); spin_unlock_irqrestore(&fxs->lasttxhooklock, flags); if (debug & DEBUG_CARD) { @@ -1817,25 +1841,25 @@ static void wctdm_fxs_hooksig(struct wctdm *wc, const int card, enum dahdi_txsig } } -static void wctdm_fxs_off_hook(struct wctdm *wc, const int card) +static void wctdm_fxs_off_hook(struct wctdm *wc, struct wctdm_module *const mod) { - struct fxs *const fxs = &wc->mods[card].mod.fxs; + struct fxs *const fxs = &mod->mod.fxs; if (debug & DEBUG_CARD) dev_info(&wc->vb.pdev->dev, - "fxs_off_hook: Card %d Going off hook\n", card); + "fxs_off_hook: Card %d Going off hook\n", mod->card); switch (fxs->lasttxhook) { case SLIC_LF_RINGING: /* Ringing */ case SLIC_LF_OHTRAN_FWD: /* Forward On Hook Transfer */ case SLIC_LF_OHTRAN_REV: /* Reverse On Hook Transfer */ /* just detected OffHook, during Ringing or OnHookTransfer */ - fxs->idletxhookstate = POLARITY_XOR(card) ? + fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; break; } - wctdm_fxs_hooksig(wc, card, DAHDI_TXSIG_OFFHOOK); - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_OFFHOOK); + wctdm_fxs_hooksig(wc, mod, DAHDI_TXSIG_OFFHOOK); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_OFFHOOK); #ifdef DEBUG if (robust) @@ -1844,27 +1868,29 @@ static void wctdm_fxs_off_hook(struct wctdm *wc, const int card) fxs->oldrxhook = 1; } -static void wctdm_fxs_on_hook(struct wctdm *wc, const int card) +static void wctdm_fxs_on_hook(struct wctdm *wc, struct wctdm_module *const mod) { - struct fxs *const fxs = &wc->mods[card].mod.fxs; - if (debug & DEBUG_CARD) + struct fxs *const fxs = &mod->mod.fxs; + if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, - "fxs_on_hook: Card %d Going on hook\n", card); - wctdm_fxs_hooksig(wc, card, DAHDI_TXSIG_ONHOOK); - dahdi_hooksig(wc->aspan->span.chans[card], DAHDI_RXSIG_ONHOOK); + "fxs_on_hook: Card %d Going on hook\n", mod->card); + } + wctdm_fxs_hooksig(wc, mod, DAHDI_TXSIG_ONHOOK); + dahdi_hooksig(&mod->chan->chan, DAHDI_RXSIG_ONHOOK); fxs->oldrxhook = 0; } -static inline void wctdm_proslic_check_hook(struct wctdm *wc, const int card) +static void +wctdm_proslic_check_hook(struct wctdm *wc, struct wctdm_module *const mod) { - struct fxs *const fxs = &wc->mods[card].mod.fxs; + struct fxs *const fxs = &mod->mod.fxs; char res; int hook; /* For some reason we have to debounce the hook detector. */ - res = wc->mods[card].cmdq.isrshadow[0]; /* Hook state */ + res = mod->cmdq.isrshadow[0]; /* Hook state */ hook = (res & 1); if (hook != fxs->lastrxhook) { @@ -1889,9 +1915,9 @@ static inline void wctdm_proslic_check_hook(struct wctdm *wc, const int card) } if (!fxs->oldrxhook && fxs->debouncehook) - wctdm_fxs_off_hook(wc, card); + wctdm_fxs_off_hook(wc, mod); else if (fxs->oldrxhook && !fxs->debouncehook) - wctdm_fxs_on_hook(wc, card); + wctdm_fxs_on_hook(wc, mod); } } fxs->lastrxhook = hook; @@ -1950,9 +1976,9 @@ static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec } /* 1ms interrupt */ -static void wctdm_isr_misc_fxs(struct wctdm *wc, int card) +static void wctdm_isr_misc_fxs(struct wctdm *wc, struct wctdm_module *const mod) { - struct fxs *const fxs = &wc->mods[card].mod.fxs; + struct fxs *const fxs = &mod->mod.fxs; unsigned long flags; if (!(wc->intcount % 10000)) { @@ -1960,17 +1986,17 @@ static void wctdm_isr_misc_fxs(struct wctdm *wc, int card) if (fxs->palarms) fxs->palarms--; } - wctdm_proslic_check_hook(wc, card); + wctdm_proslic_check_hook(wc, mod); - wctdm_proslic_check_oppending(wc, card); + wctdm_proslic_check_oppending(wc, mod); if (!(wc->intcount & 0xfc)) /* every 256ms */ - wctdm_proslic_recheck_sanity(wc, card); + wctdm_proslic_recheck_sanity(wc, mod); if (SLIC_LF_RINGING == fxs->lasttxhook) { /* RINGing, prepare for OHT */ fxs->ohttimer = OHT_TIMER << 3; /* OHT mode when idle */ - fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_OHTRAN_REV : + fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_OHTRAN_REV : SLIC_LF_OHTRAN_FWD; } else if (fxs->ohttimer) { /* check if still OnHook */ @@ -1980,39 +2006,39 @@ static void wctdm_isr_misc_fxs(struct wctdm *wc, int card) return; /* Switch to active */ - fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : + fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; spin_lock_irqsave(&fxs->lasttxhooklock, flags); if (SLIC_LF_OHTRAN_FWD == fxs->lasttxhook) { /* Apply the change if appropriate */ fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_FWD; /* Data enqueued here */ - wc->mods[card].sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); + mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer " - "stop\n", card); + "stop\n", mod->card); } } else if (SLIC_LF_OHTRAN_REV == fxs->lasttxhook) { /* Apply the change if appropriate */ fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_REV; /* Data enqueued here */ - wc->mods[card].sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); + mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook); if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer " - "stop\n", card); + "stop\n", mod->card); } } spin_unlock_irqrestore(&fxs->lasttxhooklock, flags); } else { fxs->ohttimer = 0; /* Switch to active */ - fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; + fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer abort\n", - card); + mod->card); } } @@ -2029,12 +2055,13 @@ static inline void wctdm_isr_misc(struct wctdm *wc) } for (x = 0; x < wc->mods_per_board; x++) { - switch (wc->mods[x].type) { + struct wctdm_module *const mod = &wc->mods[x]; + switch (mod->type) { case FXS: - wctdm_isr_misc_fxs(wc, x); + wctdm_isr_misc_fxs(wc, mod); break; case FXO: - wctdm_voicedaa_check_hook(wc, x); + wctdm_voicedaa_check_hook(wc, mod); break; case QRV: wctdm_qrvdri_check_hook(wc, x); @@ -2115,30 +2142,36 @@ static void handle_hx8_transmit(struct voicebus *vb, struct list_head *buffers) } } -static int wctdm_voicedaa_insane(struct wctdm *wc, int card) +static int wctdm_voicedaa_insane(struct wctdm *wc, struct wctdm_module *mod) { int blah; - blah = wctdm_getreg(wc, card, 2); + blah = wctdm_getreg(wc, mod, 2); if (blah != 0x3) return -2; - blah = wctdm_getreg(wc, card, 11); + blah = wctdm_getreg(wc, mod, 11); if (debug & DEBUG_CARD) dev_info(&wc->vb.pdev->dev, "VoiceDAA System: %02x\n", blah & 0xf); return 0; } -static int wctdm_proslic_insane(struct wctdm *wc, int card) +static int +wctdm_proslic_insane(struct wctdm *wc, struct wctdm_module *const mod) { int blah, reg1, insane_report; insane_report=0; - blah = wctdm_getreg(wc, card, 0); - if (blah != 0xff && (debug & DEBUG_CARD)) - dev_info(&wc->vb.pdev->dev, "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf)); + blah = wctdm_getreg(wc, mod, 0); + if (blah != 0xff && (debug & DEBUG_CARD)) { + dev_info(&wc->vb.pdev->dev, + "ProSLIC on module %d, product %d, " + "version %d\n", mod->card, (blah & 0x30) >> 4, + (blah & 0xf)); + } #if 0 if ((blah & 0x30) >> 4) { - dev_info(&wc->vb.pdev->dev, "ProSLIC on module %d is not a 3210.\n", card); + dev_info(&wc->vb.pdev->dev, + "ProSLIC on module %d is not a 3210.\n", mod->card); return -1; } #endif @@ -2148,99 +2181,126 @@ static int wctdm_proslic_insane(struct wctdm *wc, int card) } /* let's be really sure this is an FXS before we continue */ - reg1 = wctdm_getreg(wc, card, 1); + reg1 = wctdm_getreg(wc, mod, 1); if ((0x80 != (blah & 0xf0)) || (0x88 != reg1)) { - if (debug & DEBUG_CARD) - dev_info(&wc->vb.pdev->dev, "DEBUG: not FXS b/c reg0=%x or reg1 != 0x88 (%x).\n", blah, reg1); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "DEBUG: not FXS b/c reg0=%x or " + "reg1 != 0x88 (%x).\n", blah, reg1); + } return -1; } if ((blah & 0xf) < 2) { - dev_info(&wc->vb.pdev->dev, "ProSLIC 3210 version %d is too old\n", blah & 0xf); + dev_info(&wc->vb.pdev->dev, + "ProSLIC 3210 version %d is too old\n", blah & 0xf); return -1; } - if (wctdm_getreg(wc, card, 1) & 0x80) + + if (wctdm_getreg(wc, mod, 1) & 0x80) /* ProSLIC 3215, not a 3210 */ - wc->mods[card].flags |= FLAG_3215; + mod->flags |= FLAG_3215; - blah = wctdm_getreg(wc, card, 8); + blah = wctdm_getreg(wc, mod, 8); if (blah != 0x2) { - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d insane (1) %d should be 2\n", card, blah); + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d insane (1) %d should be 2\n", + mod->card, blah); return -1; - } else if ( insane_report) - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah); + } else if (insane_report) { + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d Reg 8 Reads %d Expected " + "is 0x2\n", mod->card, blah); + } - blah = wctdm_getreg(wc, card, 64); + blah = wctdm_getreg(wc, mod, 64); if (blah != 0x0) { - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d insane (2)\n", card); + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d insane (2)\n", + mod->card); return -1; - } else if ( insane_report) - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah); + } else if (insane_report) { + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d Reg 64 Reads %d Expected " + "is 0x0\n", mod->card, blah); + } - blah = wctdm_getreg(wc, card, 11); + blah = wctdm_getreg(wc, mod, 11); if (blah != 0x33) { - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d insane (3)\n", card); + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d insane (3)\n", mod->card); return -1; - } else if ( insane_report) - dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah); + } else if (insane_report) { + dev_notice(&wc->vb.pdev->dev, + "ProSLIC on module %d Reg 11 Reads %d " + "Expected is 0x33\n", mod->card, blah); + } /* Just be sure it's setup right. */ - wctdm_setreg(wc, card, 30, 0); + wctdm_setreg(wc, mod, 30, 0); - if (debug & DEBUG_CARD) - dev_info(&wc->vb.pdev->dev, "ProSLIC on module %d seems sane.\n", card); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, + "ProSLIC on module %d seems sane.\n", mod->card); + } return 0; } -static int wctdm_proslic_powerleak_test(struct wctdm *wc, int card) +static int +wctdm_proslic_powerleak_test(struct wctdm *wc, struct wctdm_module *const mod) { unsigned long origjiffies; unsigned char vbat; /* Turn off linefeed */ - wctdm_setreg(wc, card, LINE_STATE, 0); + wctdm_setreg(wc, mod, LINE_STATE, 0); /* Power down */ - wctdm_setreg(wc, card, 14, 0x10); + wctdm_setreg(wc, mod, 14, 0x10); /* Wait for one second */ origjiffies = jiffies; - while ((vbat = wctdm_getreg(wc, card, 82)) > 0x6) { + while ((vbat = wctdm_getreg(wc, mod, 82)) > 0x6) { if ((jiffies - origjiffies) >= (HZ/2)) break;; } if (vbat < 0x06) { - dev_notice(&wc->vb.pdev->dev, "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card, - 376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ)); + dev_notice(&wc->vb.pdev->dev, + "Excessive leakage detected on module %d: %d " + "volts (%02x) after %d ms\n", mod->card, + 376 * vbat / 1000, vbat, + (int)((jiffies - origjiffies) * 1000 / HZ)); return -1; } else if (debug & DEBUG_CARD) { - dev_info(&wc->vb.pdev->dev, "Post-leakage voltage: %d volts\n", 376 * vbat / 1000); + dev_info(&wc->vb.pdev->dev, + "Post-leakage voltage: %d volts\n", 376 * vbat / 1000); } return 0; } -static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast) +static int wctdm_powerup_proslic(struct wctdm *wc, + struct wctdm_module *mod, int fast) { unsigned char vbat; unsigned long origjiffies; int lim; /* Set period of DC-DC converter to 1/64 khz */ - wctdm_setreg(wc, card, 92, 0xc0 /* was 0xff */); + wctdm_setreg(wc, mod, 92, 0xc0 /* was 0xff */); /* Wait for VBat to powerup */ origjiffies = jiffies; /* Disable powerdown */ - wctdm_setreg(wc, card, 14, 0); + wctdm_setreg(wc, mod, 14, 0); /* If fast, don't bother checking anymore */ if (fast) return 0; - while ((vbat = wctdm_getreg(wc, card, 82)) < 0xc0) { + while ((vbat = wctdm_getreg(wc, mod, 82)) < 0xc0) { /* Wait no more than 500ms */ if ((jiffies - origjiffies) > HZ/2) { break; @@ -2249,12 +2309,14 @@ static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast) if (vbat < 0xc0) { dev_notice(&wc->vb.pdev->dev, "ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE TDM CARD??\n", - card, (int)(((jiffies - origjiffies) * 1000 / HZ)), + mod->card, (int)(((jiffies - origjiffies) * 1000 / HZ)), vbat * 375); return -1; } else if (debug & DEBUG_CARD) { - dev_info(&wc->vb.pdev->dev, "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n", - card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ))); + dev_info(&wc->vb.pdev->dev, + "ProSLIC on module %d powered up to -%d volts (%02x) " + "in %d ms\n", mod->card, vbat * 376 / 1000, vbat, + (int)(((jiffies - origjiffies) * 1000 / HZ))); } /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */ @@ -2267,29 +2329,36 @@ static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast) } else if (debug & DEBUG_CARD) dev_info(&wc->vb.pdev->dev, "Loop current set to %dmA!\n",(lim*3)+20); - wctdm_setreg(wc,card,LOOP_I_LIMIT,lim); + wctdm_setreg(wc, mod, LOOP_I_LIMIT, lim); /* Engage DC-DC converter */ - wctdm_setreg(wc, card, 93, 0x19 /* was 0x19 */); + wctdm_setreg(wc, mod, 93, 0x19 /* was 0x19 */); return 0; } -static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card) +static int +wctdm_proslic_manual_calibrate(struct wctdm *wc, struct wctdm_module *const mod) { unsigned long origjiffies; unsigned char i; - wctdm_setreg(wc, card, 21, 0);//(0) Disable all interupts in DR21 - wctdm_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21 - wctdm_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21 - wctdm_setreg(wc, card, 64, 0);//(0) + /* Disable all interupts in DR21-23 */ + wctdm_setreg(wc, mod, 21, 0); + wctdm_setreg(wc, mod, 22, 0); + wctdm_setreg(wc, mod, 23, 0); + + wctdm_setreg(wc, mod, 64, 0); + + /* (0x18) Calibrations without the ADC and DAC offset and without + * common mode calibration. */ + wctdm_setreg(wc, mod, 97, 0x18); - wctdm_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration. - wctdm_setreg(wc, card, 96, 0x47); //(0x47) Calibrate common mode and differential DAC mode DAC + ILIM + /* (0x47) Calibrate common mode and differential DAC mode DAC + ILIM */ + wctdm_setreg(wc, mod, 96, 0x47); origjiffies=jiffies; - while (wctdm_getreg(wc, card, 96) != 0) { + while (wctdm_getreg(wc, mod, 96) != 0) { if ((jiffies-origjiffies) > 80) return -1; } @@ -2299,77 +2368,88 @@ static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card) /*******************************The following is the manual gain mismatch calibration****************************/ /*******************************This is also available as a function *******************************************/ msleep(10); - wctdm_proslic_setreg_indirect(wc, card, 88,0); - wctdm_proslic_setreg_indirect(wc,card,89,0); - wctdm_proslic_setreg_indirect(wc,card,90,0); - wctdm_proslic_setreg_indirect(wc,card,91,0); - wctdm_proslic_setreg_indirect(wc,card,92,0); - wctdm_proslic_setreg_indirect(wc,card,93,0); + wctdm_proslic_setreg_indirect(wc, mod, 88, 0); + wctdm_proslic_setreg_indirect(wc, mod, 89, 0); + wctdm_proslic_setreg_indirect(wc, mod, 90, 0); + wctdm_proslic_setreg_indirect(wc, mod, 91, 0); + wctdm_proslic_setreg_indirect(wc, mod, 92, 0); + wctdm_proslic_setreg_indirect(wc, mod, 93, 0); - wctdm_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time - wctdm_setreg(wc, card, 99,0x10); + /* This is necessary if the calibration occurs other than at reset */ + wctdm_setreg(wc, mod, 98, 0x10); + wctdm_setreg(wc, mod, 99, 0x10); for ( i=0x1f; i>0; i--) { - wctdm_setreg(wc, card, 98,i); + wctdm_setreg(wc, mod, 98, i); msleep(40); - if ((wctdm_getreg(wc, card, 88)) == 0) + if ((wctdm_getreg(wc, mod, 88)) == 0) break; } // for for ( i=0x1f; i>0; i--) { - wctdm_setreg(wc, card, 99,i); + wctdm_setreg(wc, mod, 99, i); msleep(40); - if ((wctdm_getreg(wc, card, 89)) == 0) + if ((wctdm_getreg(wc, mod, 89)) == 0) break; }//for /*******************************The preceding is the manual gain mismatch calibration****************************/ /**********************************The following is the longitudinal Balance Cal***********************************/ - wctdm_setreg(wc,card,64,1); + wctdm_setreg(wc, mod, 64, 1); msleep(100); - wctdm_setreg(wc, card, 64, 0); - wctdm_setreg(wc, card, 23, 0x4); // enable interrupt for the balance Cal - wctdm_setreg(wc, card, 97, 0x1); // this is a singular calibration bit for longitudinal calibration - wctdm_setreg(wc, card, 96,0x40); + wctdm_setreg(wc, mod, 64, 0); - wctdm_getreg(wc,card,96); /* Read Reg 96 just cause */ + /* enable interrupt for the balance Cal */ + wctdm_setreg(wc, mod, 23, 0x4); - wctdm_setreg(wc, card, 21, 0xFF); - wctdm_setreg(wc, card, 22, 0xFF); - wctdm_setreg(wc, card, 23, 0xFF); + /* this is a singular calibration bit for longitudinal calibration */ + wctdm_setreg(wc, mod, 97, 0x1); + wctdm_setreg(wc, mod, 96, 0x40); + + wctdm_getreg(wc, mod, 96); /* Read Reg 96 just cause */ + + wctdm_setreg(wc, mod, 21, 0xFF); + wctdm_setreg(wc, mod, 22, 0xFF); + wctdm_setreg(wc, mod, 23, 0xFF); /**The preceding is the longitudinal Balance Cal***/ return(0); } -static int wctdm_proslic_calibrate(struct wctdm *wc, int card) +static int +wctdm_proslic_calibrate(struct wctdm *wc, struct wctdm_module *mod) { unsigned long origjiffies; int x; + /* Perform all calibrations */ - wctdm_setreg(wc, card, 97, 0x1f); + wctdm_setreg(wc, mod, 97, 0x1f); /* Begin, no speedup */ - wctdm_setreg(wc, card, 96, 0x5f); + wctdm_setreg(wc, mod, 96, 0x5f); /* Wait for it to finish */ origjiffies = jiffies; - while (wctdm_getreg(wc, card, 96)) { + while (wctdm_getreg(wc, mod, 96)) { if (time_after(jiffies, (origjiffies + (2*HZ)))) { - dev_notice(&wc->vb.pdev->dev, "Timeout waiting for calibration of module %d\n", card); + dev_notice(&wc->vb.pdev->dev, + "Timeout waiting for calibration of " + "module %d\n", mod->card); return -1; } } if (debug & DEBUG_CARD) { /* Print calibration parameters */ - dev_info(&wc->vb.pdev->dev, "Calibration Vector Regs 98 - 107: \n"); + dev_info(&wc->vb.pdev->dev, + "Calibration Vector Regs 98 - 107:\n"); for (x=98;x<108;x++) { - dev_info(&wc->vb.pdev->dev, "%d: %02x\n", x, wctdm_getreg(wc, card, x)); + dev_info(&wc->vb.pdev->dev, + "%d: %02x\n", x, wctdm_getreg(wc, mod, x)); } } return 0; @@ -2383,36 +2463,48 @@ static int wctdm_proslic_calibrate(struct wctdm *wc, int card) * tx = (0 for rx; 1 for tx) * *******************************************************************/ -static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx) +static int +wctdm_set_hwgain(struct wctdm *wc, struct wctdm_module *mod, + __s32 gain, __u32 tx) { - if (!(wc->mods[card].type == FXO)) { - dev_notice(&wc->vb.pdev->dev, "Cannot adjust gain. Unsupported module type!\n"); + if (mod->type != FXO) { + dev_notice(&wc->vb.pdev->dev, + "Cannot adjust gain. Unsupported module type!\n"); return -1; } + if (tx) { - if (debug) - dev_info(&wc->vb.pdev->dev, "setting FXO tx gain for card=%d to %d\n", card, gain); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "setting FXO tx gain for card=%d to %d\n", + mod->card, gain); + } if (gain >= -150 && gain <= 0) { - wctdm_setreg(wc, card, 38, 16 + (gain/-10)); - wctdm_setreg(wc, card, 40, 16 + (-gain%10)); + wctdm_setreg(wc, mod, 38, 16 + (gain / -10)); + wctdm_setreg(wc, mod, 40, 16 + (-gain % 10)); } else if (gain <= 120 && gain > 0) { - wctdm_setreg(wc, card, 38, gain/10); - wctdm_setreg(wc, card, 40, (gain%10)); + wctdm_setreg(wc, mod, 38, gain/10); + wctdm_setreg(wc, mod, 40, (gain%10)); } else { - dev_notice(&wc->vb.pdev->dev, "FXO tx gain is out of range (%d)\n", gain); + dev_notice(&wc->vb.pdev->dev, + "FXO tx gain is out of range (%d)\n", gain); return -1; } } else { /* rx */ - if (debug) - dev_info(&wc->vb.pdev->dev, "setting FXO rx gain for card=%d to %d\n", card, gain); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "setting FXO rx gain for card=%d to %d\n", + mod->card, gain); + } if (gain >= -150 && gain <= 0) { - wctdm_setreg(wc, card, 39, 16+ (gain/-10)); - wctdm_setreg(wc, card, 41, 16 + (-gain%10)); + wctdm_setreg(wc, mod, 39, 16 + (gain / -10)); + wctdm_setreg(wc, mod, 41, 16 + (-gain % 10)); } else if (gain <= 120 && gain > 0) { - wctdm_setreg(wc, card, 39, gain/10); - wctdm_setreg(wc, card, 41, (gain%10)); + wctdm_setreg(wc, mod, 39, gain/10); + wctdm_setreg(wc, mod, 41, (gain%10)); } else { - dev_notice(&wc->vb.pdev->dev, "FXO rx gain is out of range (%d)\n", gain); + dev_notice(&wc->vb.pdev->dev, + "FXO rx gain is out of range (%d)\n", gain); return -1; } } @@ -2445,10 +2537,10 @@ static int set_lasttxhook_interruptible(struct fxs *fxs, unsigned newval, int * } /* Must be called from within an interruptible context */ -static int set_vmwi(struct wctdm *wc, int chan_idx) +static int set_vmwi(struct wctdm *wc, struct wctdm_module *const mod) { int x; - struct fxs *const fxs = &wc->mods[chan_idx].mod.fxs; + struct fxs *const fxs = &mod->mod.fxs; /* Presently only supports line reversal MWI */ if ((fxs->vmwi_active_messages) && @@ -2458,15 +2550,14 @@ static int set_vmwi(struct wctdm *wc, int chan_idx) fxs->vmwi_linereverse = 0; /* Set line polarity for new VMWI state */ - if (POLARITY_XOR(chan_idx)) { + if (POLARITY_XOR(fxs)) { fxs->idletxhookstate |= SLIC_LF_REVMASK; /* Do not set while currently ringing or open */ if (((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_RINGING) && ((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_OPEN)) { x = fxs->lasttxhook; x |= SLIC_LF_REVMASK; - set_lasttxhook_interruptible(fxs, x, - &wc->mods[chan_idx].sethook); + set_lasttxhook_interruptible(fxs, x, &mod->sethook); } } else { fxs->idletxhookstate &= ~SLIC_LF_REVMASK; @@ -2475,140 +2566,169 @@ static int set_vmwi(struct wctdm *wc, int chan_idx) ((fxs->lasttxhook & SLIC_LF_SETMASK) != SLIC_LF_OPEN)) { x = fxs->lasttxhook; x &= ~SLIC_LF_REVMASK; - set_lasttxhook_interruptible(fxs, x, - &wc->mods[chan_idx].sethook); + set_lasttxhook_interruptible(fxs, x, &mod->sethook); } } if (debug) { dev_info(&wc->vb.pdev->dev, "Setting VMWI on channel %d, messages=%d, lrev=%d\n", - chan_idx, fxs->vmwi_active_messages, + mod->card, fxs->vmwi_active_messages, fxs->vmwi_linereverse); } return 0; } -static void wctdm_voicedaa_set_ts(struct wctdm *wc, int card, int ts) +static void +wctdm_voicedaa_set_ts(struct wctdm *wc, struct wctdm_module *mod, int ts) { - wctdm_setreg(wc, card, 34, (ts * 8) & 0xff); - wctdm_setreg(wc, card, 35, (ts * 8) >> 8); - wctdm_setreg(wc, card, 36, (ts * 8) & 0xff); - wctdm_setreg(wc, card, 37, (ts * 8) >> 8); + wctdm_setreg(wc, mod, 34, (ts * 8) & 0xff); + wctdm_setreg(wc, mod, 35, (ts * 8) >> 8); + wctdm_setreg(wc, mod, 36, (ts * 8) & 0xff); + wctdm_setreg(wc, mod, 37, (ts * 8) >> 8); - if (debug) - dev_info(&wc->vb.pdev->dev, "voicedaa: card %d new timeslot: %d\n", card + 1, ts); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "voicedaa: card %d new timeslot: %d\n", + mod->card + 1, ts); + } } -static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane) +static int +wctdm_init_voicedaa(struct wctdm *wc, struct wctdm_module *mod, + int fast, int manual, int sane) { unsigned char reg16=0, reg26=0, reg30=0, reg31=0; unsigned long flags; long newjiffies; +#if 0 /* TODO */ if ((wc->mods[card & 0xfc].type == QRV) || (wc->mods[card & 0xfc].type == BRI)) return -2; +#endif spin_lock_irqsave(&wc->reglock, flags); - wc->mods[card].type = NONE; + mod->type = NONE; spin_unlock_irqrestore(&wc->reglock, flags); msleep(100); spin_lock_irqsave(&wc->reglock, flags); - wc->mods[card].type = FXO; + mod->type = FXO; spin_unlock_irqrestore(&wc->reglock, flags); msleep(100); - if (!sane && wctdm_voicedaa_insane(wc, card)) + if (!sane && wctdm_voicedaa_insane(wc, mod)) return -2; /* Software reset */ - wctdm_setreg(wc, card, 1, 0x80); + wctdm_setreg(wc, mod, 1, 0x80); msleep(100); /* Set On-hook speed, Ringer impedence, and ringer threshold */ reg16 |= (fxo_modes[_opermode].ohs << 6); reg16 |= (fxo_modes[_opermode].rz << 1); reg16 |= (fxo_modes[_opermode].rt); - wctdm_setreg(wc, card, 16, reg16); + wctdm_setreg(wc, mod, 16, reg16); /* Enable ring detector full-wave rectifier mode */ - wctdm_setreg(wc, card, 18, 2); - wctdm_setreg(wc, card, 24, 0); + wctdm_setreg(wc, mod, 18, 2); + wctdm_setreg(wc, mod, 24, 0); /* Set DC Termination: Tip/Ring voltage adjust, minimum operational current, current limitation */ reg26 |= (fxo_modes[_opermode].dcv << 6); reg26 |= (fxo_modes[_opermode].mini << 4); reg26 |= (fxo_modes[_opermode].ilim << 1); - wctdm_setreg(wc, card, 26, reg26); + wctdm_setreg(wc, mod, 26, reg26); /* Set AC Impedence */ reg30 = (fxo_modes[_opermode].acim); - wctdm_setreg(wc, card, 30, reg30); + wctdm_setreg(wc, mod, 30, reg30); /* Misc. DAA parameters */ reg31 = 0xa3; reg31 |= (fxo_modes[_opermode].ohs2 << 3); - wctdm_setreg(wc, card, 31, reg31); + wctdm_setreg(wc, mod, 31, reg31); - wctdm_voicedaa_set_ts(wc, card, card); + wctdm_voicedaa_set_ts(wc, mod, mod->card); /* Enable ISO-Cap */ - wctdm_setreg(wc, card, 6, 0x00); + wctdm_setreg(wc, mod, 6, 0x00); /* Wait 1000ms for ISO-cap to come up */ newjiffies = jiffies; newjiffies += 2 * HZ; - while ((jiffies < newjiffies) && !(wctdm_getreg(wc, card, 11) & 0xf0)) + + while ((jiffies < newjiffies) && !(wctdm_getreg(wc, mod, 11) & 0xf0)) msleep(100); - if (!(wctdm_getreg(wc, card, 11) & 0xf0)) { + if (!(wctdm_getreg(wc, mod, 11) & 0xf0)) { dev_notice(&wc->vb.pdev->dev, "VoiceDAA did not bring up ISO link properly!\n"); return -1; } - if (debug & DEBUG_CARD) + + if (debug & DEBUG_CARD) { dev_info(&wc->vb.pdev->dev, "ISO-Cap is now up, line side: %02x rev %02x\n", - wctdm_getreg(wc, card, 11) >> 4, - (wctdm_getreg(wc, card, 13) >> 2) & 0xf); + wctdm_getreg(wc, mod, 11) >> 4, + (wctdm_getreg(wc, mod, 13) >> 2) & 0xf); + } + /* Enable on-hook line monitor */ - wctdm_setreg(wc, card, 5, 0x08); + wctdm_setreg(wc, mod, 5, 0x08); /* Take values for fxotxgain and fxorxgain and apply them to module */ - wctdm_set_hwgain(wc, card, fxotxgain, 1); - wctdm_set_hwgain(wc, card, fxorxgain, 0); + wctdm_set_hwgain(wc, mod, fxotxgain, 1); + wctdm_set_hwgain(wc, mod, fxorxgain, 0); #ifdef DEBUG if (digitalloopback) { dev_info(&wc->vb.pdev->dev, "Turning on digital loopback for port %d.\n", - card + 1); - wctdm_setreg(wc, card, 10, 0x01); + mod->card + 1); + wctdm_setreg(wc, mod, 10, 0x01); } #endif - if (debug) - dev_info(&wc->vb.pdev->dev, "DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", (wctdm_getreg(wc, card, 38)/16) ? -(wctdm_getreg(wc, card, 38) - 16) : wctdm_getreg(wc, card, 38), (wctdm_getreg(wc, card, 40)/16) ? -(wctdm_getreg(wc, card, 40) - 16) : wctdm_getreg(wc, card, 40), (wctdm_getreg(wc, card, 39)/16) ? -(wctdm_getreg(wc, card, 39) - 16): wctdm_getreg(wc, card, 39), (wctdm_getreg(wc, card, 41)/16)?-(wctdm_getreg(wc, card, 41) - 16) : wctdm_getreg(wc, card, 41)); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", + (wctdm_getreg(wc, mod, 38)/16) ? + -(wctdm_getreg(wc, mod, 38) - 16) : + wctdm_getreg(wc, mod, 38), + (wctdm_getreg(wc, mod, 40)/16) ? + -(wctdm_getreg(wc, mod, 40) - 16) : + wctdm_getreg(wc, mod, 40), + (wctdm_getreg(wc, mod, 39)/16) ? + -(wctdm_getreg(wc, mod, 39) - 16) : + wctdm_getreg(wc, mod, 39), + (wctdm_getreg(wc, mod, 41)/16) ? + -(wctdm_getreg(wc, mod, 41) - 16) : + wctdm_getreg(wc, mod, 41)); + } return 0; - } -static void wctdm_proslic_set_ts(struct wctdm *wc, int card, int ts) +static void +wctdm_proslic_set_ts(struct wctdm *wc, struct wctdm_module *mod, int ts) { - wctdm_setreg(wc, card, 2, (ts * 8) & 0xff); /* Tx Start count low byte 0 */ - wctdm_setreg(wc, card, 3, (ts * 8) >> 8); /* Tx Start count high byte 0 */ - wctdm_setreg(wc, card, 4, (ts * 8) & 0xff); /* Rx Start count low byte 0 */ - wctdm_setreg(wc, card, 5, (ts * 8) >> 8); /* Rx Start count high byte 0 */ + wctdm_setreg(wc, mod, 2, (ts * 8) & 0xff); /* Tx Start low byte 0 */ + wctdm_setreg(wc, mod, 3, (ts * 8) >> 8); /* Tx Start high byte 0 */ + wctdm_setreg(wc, mod, 4, (ts * 8) & 0xff); /* Rx Start low byte 0 */ + wctdm_setreg(wc, mod, 5, (ts * 8) >> 8); /* Rx Start high byte 0 */ - if (debug) - dev_info(&wc->vb.pdev->dev, "proslic: card %d new timeslot: %d\n", card + 1, ts); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "proslic: card %d new timeslot: %d\n", + mod->card + 1, ts); + } } -static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int sane) +static int +wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod, + int fast, int manual, int sane) { - struct wctdm_module *const mod = &wc->mods[card]; struct fxs *const fxs = &mod->mod.fxs; unsigned short tmp[5]; unsigned long flags; @@ -2616,8 +2736,10 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int x; int fxsmode=0; - if (wc->mods[card & 0xfc].type == QRV) +#if 0 /* TODO */ + if (wc->mods[mod->card & 0xfc].type == QRV) return -2; +#endif spin_lock_irqsave(&wc->reglock, flags); mod->type = FXS; @@ -2626,7 +2748,7 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, msleep(100); /* Sanity check the ProSLIC */ - if (!sane && wctdm_proslic_insane(wc, card)) + if (!sane && wctdm_proslic_insane(wc, mod)) return -2; /* Initialize VMWI settings */ @@ -2641,41 +2763,45 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, if (sane) { /* Make sure we turn off the DC->DC converter to prevent anything from blowing up */ - wctdm_setreg(wc, card, 14, 0x10); + wctdm_setreg(wc, mod, 14, 0x10); } - if (wctdm_proslic_init_indirect_regs(wc, card)) { - dev_info(&wc->vb.pdev->dev, "Indirect Registers failed to initialize on module %d.\n", card); + if (wctdm_proslic_init_indirect_regs(wc, mod)) { + dev_info(&wc->vb.pdev->dev, + "Indirect Registers failed to initialize on " + "module %d.\n", mod->card); return -1; } /* Clear scratch pad area */ - wctdm_proslic_setreg_indirect(wc, card, 97,0); + wctdm_proslic_setreg_indirect(wc, mod, 97, 0); /* Clear digital loopback */ - wctdm_setreg(wc, card, 8, 0); + wctdm_setreg(wc, mod, 8, 0); /* Revision C optimization */ - wctdm_setreg(wc, card, 108, 0xeb); + wctdm_setreg(wc, mod, 108, 0xeb); /* Disable automatic VBat switching for safety to prevent - Q7 from accidently turning on and burning out. */ - wctdm_setreg(wc, card, 67, 0x07); /* If pulse dialing has trouble at high REN - loads change this to 0x17 */ + * Q7 from accidently turning on and burning out. + * If pulse dialing has trouble at high REN loads change this to 0x17 */ + wctdm_setreg(wc, mod, 67, 0x07); /* Turn off Q7 */ - wctdm_setreg(wc, card, 66, 1); + wctdm_setreg(wc, mod, 66, 1); /* Flush ProSLIC digital filters by setting to clear, while saving old values */ for (x=0;x<5;x++) { - tmp[x] = wctdm_proslic_getreg_indirect(wc, card, x + 35); - wctdm_proslic_setreg_indirect(wc, card, x + 35, 0x8000); + tmp[x] = wctdm_proslic_getreg_indirect(wc, mod, x + 35); + wctdm_proslic_setreg_indirect(wc, mod, x + 35, 0x8000); } /* Power up the DC-DC converter */ - if (wctdm_powerup_proslic(wc, card, fast)) { - dev_notice(&wc->vb.pdev->dev, "Unable to do INITIAL ProSLIC powerup on module %d\n", card); + if (wctdm_powerup_proslic(wc, mod, fast)) { + dev_notice(&wc->vb.pdev->dev, + "Unable to do INITIAL ProSLIC powerup on " + "module %d\n", mod->card); return -1; } @@ -2683,20 +2809,24 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, spin_lock_init(&fxs->lasttxhooklock); /* Check for power leaks */ - if (wctdm_proslic_powerleak_test(wc, card)) { - dev_notice(&wc->vb.pdev->dev, "ProSLIC module %d failed leakage test. Check for short circuit\n", card); + if (wctdm_proslic_powerleak_test(wc, mod)) { + dev_notice(&wc->vb.pdev->dev, + "ProSLIC module %d failed leakage test. " + "Check for short circuit\n", mod->card); } /* Power up again */ - if (wctdm_powerup_proslic(wc, card, fast)) { - dev_notice(&wc->vb.pdev->dev, "Unable to do FINAL ProSLIC powerup on module %d\n", card); + if (wctdm_powerup_proslic(wc, mod, fast)) { + dev_notice(&wc->vb.pdev->dev, + "Unable to do FINAL ProSLIC powerup on " + "module %d\n", mod->card); return -1; } #ifndef NO_CALIBRATION /* Perform calibration */ if (manual) { - if (wctdm_proslic_manual_calibrate(wc, card)) { + if (wctdm_proslic_manual_calibrate(wc, mod)) { //dev_notice(&wc->vb.pdev->dev, "Proslic failed on Manual Calibration\n"); - if (wctdm_proslic_manual_calibrate(wc, card)) { + if (wctdm_proslic_manual_calibrate(wc, mod)) { dev_notice(&wc->vb.pdev->dev, "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n"); return -1; } @@ -2704,9 +2834,9 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, } } else { - if (wctdm_proslic_calibrate(wc, card)) { + if (wctdm_proslic_calibrate(wc, mod)) { //dev_notice(&wc->vb.pdev->dev, "ProSlic died on Auto Calibration.\n"); - if (wctdm_proslic_calibrate(wc, card)) { + if (wctdm_proslic_calibrate(wc, mod)) { dev_notice(&wc->vb.pdev->dev, "Proslic Failed on Second Attempt to Auto Calibrate\n"); return -1; } @@ -2714,29 +2844,29 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, } } /* Perform DC-DC calibration */ - wctdm_setreg(wc, card, 93, 0x99); - r19 = wctdm_getreg(wc, card, 107); + wctdm_setreg(wc, mod, 93, 0x99); + r19 = wctdm_getreg(wc, mod, 107); if ((r19 < 0x2) || (r19 > 0xd)) { dev_notice(&wc->vb.pdev->dev, "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19); - wctdm_setreg(wc, card, 107, 0x8); + wctdm_setreg(wc, mod, 107, 0x8); } /* Save calibration vectors */ for (x = 0; x < NUM_CAL_REGS; x++) - fxs->calregs.vals[x] = wctdm_getreg(wc, card, 96 + x); + fxs->calregs.vals[x] = wctdm_getreg(wc, mod, 96 + x); #endif } else { /* Restore calibration registers */ for (x = 0; x < NUM_CAL_REGS; x++) - wctdm_setreg(wc, card, 96 + x, fxs->calregs.vals[x]); + wctdm_setreg(wc, mod, 96 + x, fxs->calregs.vals[x]); } /* Calibration complete, restore original values */ for (x=0;x<5;x++) { - wctdm_proslic_setreg_indirect(wc, card, x + 35, tmp[x]); + wctdm_proslic_setreg_indirect(wc, mod, x + 35, tmp[x]); } - if (wctdm_proslic_verify_indirect_regs(wc, card)) { + if (wctdm_proslic_verify_indirect_regs(wc, mod)) { dev_info(&wc->vb.pdev->dev, "Indirect Registers failed verification.\n"); return -1; } @@ -2756,26 +2886,31 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, #endif /* U-Law 8-bit interface */ - wctdm_proslic_set_ts(wc, card, card); + wctdm_proslic_set_ts(wc, mod, mod->card); + + wctdm_setreg(wc, mod, 18, 0xff); /* clear all interrupt */ + wctdm_setreg(wc, mod, 19, 0xff); + wctdm_setreg(wc, mod, 20, 0xff); + wctdm_setreg(wc, mod, 22, 0xff); + wctdm_setreg(wc, mod, 73, 0x04); - wctdm_setreg(wc, card, 18, 0xff); // clear all interrupt - wctdm_setreg(wc, card, 19, 0xff); - wctdm_setreg(wc, card, 20, 0xff); - wctdm_setreg(wc, card, 22, 0xff); - wctdm_setreg(wc, card, 73, 0x04); if (fxshonormode) { static const int ACIM2TISS[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 }; fxsmode = ACIM2TISS[fxo_modes[_opermode].acim]; - wctdm_setreg(wc, card, 10, 0x08 | fxsmode); - if (fxo_modes[_opermode].ring_osc) - wctdm_proslic_setreg_indirect(wc, card, 20, fxo_modes[_opermode].ring_osc); - if (fxo_modes[_opermode].ring_x) - wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x); + wctdm_setreg(wc, mod, 10, 0x08 | fxsmode); + if (fxo_modes[_opermode].ring_osc) { + wctdm_proslic_setreg_indirect(wc, mod, 20, + fxo_modes[_opermode].ring_osc); + } + if (fxo_modes[_opermode].ring_x) { + wctdm_proslic_setreg_indirect(wc, mod, 21, + fxo_modes[_opermode].ring_x); + } } - if (lowpower) - wctdm_setreg(wc, card, 72, 0x10); + if (lowpower) + wctdm_setreg(wc, mod, 72, 0x10); #if 0 wctdm_setreg(wc, card, 21, 0x00); // enable interrupt @@ -2793,36 +2928,46 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, if (fastringer) { /* Speed up Ringer */ - wctdm_proslic_setreg_indirect(wc, card, 20, 0x7e6d); - wctdm_proslic_setreg_indirect(wc, card, 21, 0x01b9); + wctdm_proslic_setreg_indirect(wc, mod, 20, 0x7e6d); + wctdm_proslic_setreg_indirect(wc, mod, 21, 0x01b9); /* Beef up Ringing voltage to 89V */ if (boostringer) { - wctdm_setreg(wc, card, 74, 0x3f); - if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247)) + wctdm_setreg(wc, mod, 74, 0x3f); + if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x247)) return -1; - dev_info(&wc->vb.pdev->dev, "Boosting fast ringer on slot %d (89V peak)\n", card + 1); + dev_info(&wc->vb.pdev->dev, + "Boosting fast ringer on slot %d (89V peak)\n", + mod->card + 1); } else if (lowpower) { - if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b)) + if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x14b)) return -1; - dev_info(&wc->vb.pdev->dev, "Reducing fast ring power on slot %d (50V peak)\n", card + 1); + dev_info(&wc->vb.pdev->dev, + "Reducing fast ring power on slot %d " + "(50V peak)\n", mod->card + 1); } else - dev_info(&wc->vb.pdev->dev, "Speeding up ringer on slot %d (25Hz)\n", card + 1); + dev_info(&wc->vb.pdev->dev, + "Speeding up ringer on slot %d (25Hz)\n", + mod->card + 1); } else { /* Beef up Ringing voltage to 89V */ if (boostringer) { - wctdm_setreg(wc, card, 74, 0x3f); - if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1)) + wctdm_setreg(wc, mod, 74, 0x3f); + if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x1d1)) return -1; - dev_info(&wc->vb.pdev->dev, "Boosting ringer on slot %d (89V peak)\n", card + 1); + dev_info(&wc->vb.pdev->dev, + "Boosting ringer on slot %d (89V peak)\n", + mod->card + 1); } else if (lowpower) { - if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108)) + if (wctdm_proslic_setreg_indirect(wc, mod, 21, 0x108)) return -1; - dev_info(&wc->vb.pdev->dev, "Reducing ring power on slot %d (50V peak)\n", card + 1); + dev_info(&wc->vb.pdev->dev, + "Reducing ring power on slot %d " + "(50V peak)\n", mod->card + 1); } } if (fxstxgain || fxsrxgain) { - r9 = wctdm_getreg(wc, card, 9); + r9 = wctdm_getreg(wc, mod, 9); switch (fxstxgain) { case 35: @@ -2846,208 +2991,232 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, case 0: break; } - wctdm_setreg(wc, card, 9, r9); + wctdm_setreg(wc, mod, 9, r9); } - if (debug) - dev_info(&wc->vb.pdev->dev, "DEBUG: fxstxgain:%s fxsrxgain:%s\n",((wctdm_getreg(wc, card, 9)/8) == 1)?"3.5":(((wctdm_getreg(wc,card,9)/4) == 1)?"-3.5":"0.0"),((wctdm_getreg(wc, card, 9)/2) == 1)?"3.5":((wctdm_getreg(wc,card,9)%2)?"-3.5":"0.0")); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "DEBUG: fxstxgain:%s fxsrxgain:%s\n", + ((wctdm_getreg(wc, mod, 9) / 8) == 1) ? + "3.5" : (((wctdm_getreg(wc, mod, 9) / 4) == 1) ? + "-3.5" : "0.0"), + ((wctdm_getreg(wc, mod, 9) / 2) == 1) ? + "3.5" : ((wctdm_getreg(wc, mod, 9) % 2) ? + "-3.5" : "0.0")); + } - fxs->lasttxhook = wc->mods[card].mod.fxs.idletxhookstate; - wctdm_setreg(wc, card, LINE_STATE, fxs->lasttxhook); + fxs->lasttxhook = fxs->idletxhookstate; + wctdm_setreg(wc, mod, LINE_STATE, fxs->lasttxhook); return 0; } -static void wctdm_qrvdri_set_ts(struct wctdm *wc, int card, int ts) +static void +wctdm_qrvdri_set_ts(struct wctdm *wc, struct wctdm_module *mod, int ts) { - wctdm_setreg(wc, card, 0x13, ts + 0x80); /* codec 2 tx, ts0 */ - wctdm_setreg(wc, card, 0x17, ts + 0x80); /* codec 0 rx, ts0 */ - wctdm_setreg(wc, card, 0x14, ts + 0x81); /* codec 1 tx, ts1 */ - wctdm_setreg(wc, card, 0x18, ts + 0x81); /* codec 1 rx, ts1 */ + wctdm_setreg(wc, mod, 0x13, ts + 0x80); /* codec 2 tx, ts0 */ + wctdm_setreg(wc, mod, 0x17, ts + 0x80); /* codec 0 rx, ts0 */ + wctdm_setreg(wc, mod, 0x14, ts + 0x81); /* codec 1 tx, ts1 */ + wctdm_setreg(wc, mod, 0x18, ts + 0x81); /* codec 1 rx, ts1 */ - if (debug) - dev_info(&wc->vb.pdev->dev, "qrvdri: card %d new timeslot: %d\n", card + 1, ts); + if (debug) { + dev_info(&wc->vb.pdev->dev, + "qrvdri: card %d new timeslot: %d\n", + mod->card + 1, ts); + } } static int wctdm_init_qrvdri(struct wctdm *wc, int card) { + struct wctdm_module *const mod = &wc->mods[card]; unsigned char x,y; if (BRI == wc->mods[card & 0xfc].type) return -2; /* have to set this, at least for now */ - wc->mods[card].type = QRV; - if (!(card & 3)) /* if at base of card, reset and write it */ - { - wctdm_setreg(wc,card,0,0x80); - wctdm_setreg(wc,card,0,0x55); - wctdm_setreg(wc,card,1,0x69); - wc->mods[card].mod.qrv.hook = wc->mods[card + 1].mod.qrv.hook = 0; - wc->mods[card + 2].mod.qrv.hook = wc->mods[card + 3].mod.qrv.hook = 0xff; - wc->mods[card].mod.qrv.debouncetime = wc->mods[card + 1].mod.qrv.debouncetime = QRV_DEBOUNCETIME; - wc->mods[card].mod.qrv.debtime = wc->mods[card + 1].mod.qrv.debtime = 0; - wc->mods[card].mod.qrv.radmode = wc->mods[card + 1].mod.qrv.radmode = 0; - wc->mods[card].mod.qrv.txgain = wc->mods[card + 1].mod.qrv.txgain = 3599; - wc->mods[card].mod.qrv.rxgain = wc->mods[card + 1].mod.qrv.rxgain = 1199; + mod->type = QRV; + if (!(card & 3)) { /* if at base of card, reset and write it */ + struct qrv *const qrv = &mod->mod.qrv; + struct qrv *const qrv1 = &wc->mods[card + 1].mod.qrv; + struct qrv *const qrv2 = &wc->mods[card + 2].mod.qrv; + struct qrv *const qrv3 = &wc->mods[card + 3].mod.qrv; + + wctdm_setreg(wc, mod, 0, 0x80); + wctdm_setreg(wc, mod, 0, 0x55); + wctdm_setreg(wc, mod, 1, 0x69); + qrv->hook = qrv1->hook = 0; + qrv2->hook = qrv3->hook = 0xff; + qrv->debouncetime = qrv1->debouncetime = QRV_DEBOUNCETIME; + qrv->debtime = qrv1->debtime = 0; + qrv->radmode = qrv1->radmode = 0; + qrv->txgain = qrv1->txgain = 3599; + qrv->rxgain = qrv1->rxgain = 1199; } else { /* channel is on same card as base, no need to test */ if (wc->mods[card & 0x7c].type == QRV) { /* only lower 2 are valid */ if (!(card & 2)) return 0; } - wc->mods[card].type = NONE; + mod->type = NONE; return 1; } - x = wctdm_getreg(wc,card,0); - y = wctdm_getreg(wc,card,1); + x = wctdm_getreg(wc, mod, 0); + y = wctdm_getreg(wc, mod, 1); /* if not a QRV card, return as such */ if ((x != 0x55) || (y != 0x69)) { - wc->mods[card].type = NONE; + mod->type = NONE; return 1; } - for (x = 0; x < 0x30; x++) - { - if ((x >= 0x1c) && (x <= 0x1e)) wctdm_setreg(wc,card,x,0xff); - else wctdm_setreg(wc,card,x,0); + for (x = 0; x < 0x30; x++) { + if ((x >= 0x1c) && (x <= 0x1e)) + wctdm_setreg(wc, mod, x, 0xff); + else + wctdm_setreg(wc, mod, x, 0); } - wctdm_setreg(wc,card,0,0x80); + wctdm_setreg(wc, mod, 0, 0x80); msleep(100); - wctdm_setreg(wc,card,0,0x10); - wctdm_setreg(wc,card,0,0x10); + wctdm_setreg(wc, mod, 0, 0x10); + wctdm_setreg(wc, mod, 0, 0x10); msleep(100); /* set up modes */ - wctdm_setreg(wc,card,0,0x1c); + wctdm_setreg(wc, mod, 0, 0x1c); /* set up I/O directions */ - wctdm_setreg(wc,card,1,0x33); - wctdm_setreg(wc,card,2,0x0f); - wctdm_setreg(wc,card,5,0x0f); + wctdm_setreg(wc, mod, 1, 0x33); + wctdm_setreg(wc, mod, 2, 0x0f); + wctdm_setreg(wc, mod, 5, 0x0f); /* set up I/O to quiescent state */ - wctdm_setreg(wc,card,3,0x11); /* D0-7 */ - wctdm_setreg(wc,card,4,0xa); /* D8-11 */ - wctdm_setreg(wc,card,7,0); /* CS outputs */ + wctdm_setreg(wc, mod, 3, 0x11); /* D0-7 */ + wctdm_setreg(wc, mod, 4, 0xa); /* D8-11 */ + wctdm_setreg(wc, mod, 7, 0); /* CS outputs */ - wctdm_qrvdri_set_ts(wc, card, card); + wctdm_qrvdri_set_ts(wc, mod, card); /* set up for max gains */ - wctdm_setreg(wc,card,0x26,0x24); - wctdm_setreg(wc,card,0x27,0x24); - wctdm_setreg(wc,card,0x0b,0x01); /* "Transmit" gain codec 0 */ - wctdm_setreg(wc,card,0x0c,0x01); /* "Transmit" gain codec 1 */ - wctdm_setreg(wc,card,0x0f,0xff); /* "Receive" gain codec 0 */ - wctdm_setreg(wc,card,0x10,0xff); /* "Receive" gain codec 1 */ + wctdm_setreg(wc, mod, 0x26, 0x24); + wctdm_setreg(wc, mod, 0x27, 0x24); + wctdm_setreg(wc, mod, 0x0b, 0x01); /* "Transmit" gain codec 0 */ + wctdm_setreg(wc, mod, 0x0c, 0x01); /* "Transmit" gain codec 1 */ + wctdm_setreg(wc, mod, 0x0f, 0xff); /* "Receive" gain codec 0 */ + wctdm_setreg(wc, mod, 0x10, 0xff); /* "Receive" gain codec 1 */ return 0; } -static void qrv_dosetup(struct dahdi_chan *chan,struct wctdm *wc) +static void qrv_dosetup(struct dahdi_chan *chan, struct wctdm *wc) { + struct wctdm_module *qrvmod; + struct wctdm_module *nextqrvmod; int qrvcard; unsigned char r; long l; /* actually do something with the values */ qrvcard = (chan->chanpos - 1) & 0xfc; + qrvmod = &wc->mods[qrvcard]; + nextqrvmod = &wc->mods[qrvcard + 1]; if (debug) { dev_info(&wc->vb.pdev->dev, "@@@@@ radmodes: %d,%d rxgains: %d,%d " "txgains: %d,%d\n", wc->mods[qrvcard].mod.qrv.radmode, - wc->mods[qrvcard + 1].mod.qrv.radmode, - wc->mods[qrvcard].mod.qrv.rxgain, wc->mods[qrvcard + 1].mod.qrv.rxgain, + nextqrvmod->mod.qrv.radmode, + wc->mods[qrvcard].mod.qrv.rxgain, + nextqrvmod->mod.qrv.rxgain, wc->mods[qrvcard].mod.qrv.txgain, - wc->mods[qrvcard + 1].mod.qrv.txgain); + nextqrvmod->mod.qrv.txgain); } r = 0; - if (wc->mods[qrvcard].mod.qrv.radmode & RADMODE_DEEMP) + if (qrvmod->mod.qrv.radmode & RADMODE_DEEMP) r |= 4; - if (wc->mods[qrvcard + 1].mod.qrv.radmode & RADMODE_DEEMP) + if (nextqrvmod->mod.qrv.radmode & RADMODE_DEEMP) r |= 8; - if (wc->mods[qrvcard].mod.qrv.rxgain < 1200) + if (qrvmod->mod.qrv.rxgain < 1200) r |= 1; - if (wc->mods[qrvcard + 1].mod.qrv.rxgain < 1200) + if (nextqrvmod->mod.qrv.rxgain < 1200) r |= 2; - wctdm_setreg(wc, qrvcard, 7, r); + wctdm_setreg(wc, qrvmod, 7, r); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 7 to %02x hex\n",r); r = 0; - if (wc->mods[qrvcard].mod.qrv.radmode & RADMODE_PREEMP) + if (qrvmod->mod.qrv.radmode & RADMODE_PREEMP) r |= 3; - else if (wc->mods[qrvcard].mod.qrv.txgain >= 3600) + else if (qrvmod->mod.qrv.txgain >= 3600) r |= 1; - else if (wc->mods[qrvcard].mod.qrv.txgain >= 1200) + else if (qrvmod->mod.qrv.txgain >= 1200) r |= 2; - if (wc->mods[qrvcard + 1].mod.qrv.radmode & RADMODE_PREEMP) + if (nextqrvmod->mod.qrv.radmode & RADMODE_PREEMP) r |= 0xc; - else if (wc->mods[qrvcard + 1].mod.qrv.txgain >= 3600) + else if (nextqrvmod->mod.qrv.txgain >= 3600) r |= 4; - else if (wc->mods[qrvcard + 1].mod.qrv.txgain >= 1200) + else if (nextqrvmod->mod.qrv.txgain >= 1200) r |= 8; - wctdm_setreg(wc, qrvcard, 4, r); + wctdm_setreg(wc, qrvmod, 4, r); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 4 to %02x hex\n",r); r = 0; - if (wc->mods[qrvcard].mod.qrv.rxgain >= 2400) + if (qrvmod->mod.qrv.rxgain >= 2400) r |= 1; - if (wc->mods[qrvcard + 1].mod.qrv.rxgain >= 2400) + if (nextqrvmod->mod.qrv.rxgain >= 2400) r |= 2; - wctdm_setreg(wc, qrvcard, 0x25, r); + wctdm_setreg(wc, qrvmod, 0x25, r); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x25 to %02x hex\n",r); r = 0; - if (wc->mods[qrvcard].mod.qrv.txgain < 2400) + if (qrvmod->mod.qrv.txgain < 2400) r |= 1; else r |= 4; - if (wc->mods[qrvcard + 1].mod.qrv.txgain < 2400) + if (nextqrvmod->mod.qrv.txgain < 2400) r |= 8; else r |= 0x20; - wctdm_setreg(wc, qrvcard, 0x26, r); + wctdm_setreg(wc, qrvmod, 0x26, r); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x26 to %02x hex\n",r); - l = ((long)(wc->mods[qrvcard].mod.qrv.rxgain % 1200) * 10000) / 46875; + l = ((long)(qrvmod->mod.qrv.rxgain % 1200) * 10000) / 46875; if (l == 0) l = 1; - if (wc->mods[qrvcard].mod.qrv.rxgain >= 2400) + if (qrvmod->mod.qrv.rxgain >= 2400) l += 181; - wctdm_setreg(wc, qrvcard, 0x0b, (unsigned char)l); + wctdm_setreg(wc, qrvmod, 0x0b, (unsigned char)l); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x0b to %02x hex\n",(unsigned char)l); - l = ((long)(wc->mods[qrvcard + 1].mod.qrv.rxgain % 1200) * 10000) / 46875; + l = ((long)(nextqrvmod->mod.qrv.rxgain % 1200) * 10000) / 46875; if (l == 0) l = 1; - if (wc->mods[qrvcard + 1].mod.qrv.rxgain >= 2400) + if (nextqrvmod->mod.qrv.rxgain >= 2400) l += 181; - wctdm_setreg(wc, qrvcard, 0x0c, (unsigned char)l); + wctdm_setreg(wc, qrvmod, 0x0c, (unsigned char)l); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x0c to %02x hex\n",(unsigned char)l); - l = ((long)(wc->mods[qrvcard].mod.qrv.txgain % 1200) * 10000) / 46875; + l = ((long)(qrvmod->mod.qrv.txgain % 1200) * 10000) / 46875; if (l == 0) l = 1; - wctdm_setreg(wc, qrvcard, 0x0f, (unsigned char)l); + wctdm_setreg(wc, qrvmod, 0x0f, (unsigned char)l); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x0f to %02x hex\n", (unsigned char)l); - l = ((long)(wc->mods[qrvcard + 1].mod.qrv.txgain % 1200) * 10000) / 46875; + l = ((long)(nextqrvmod->mod.qrv.txgain % 1200) * 10000) / 46875; if (l == 0) l = 1; - wctdm_setreg(wc, qrvcard, 0x10,(unsigned char)l); + wctdm_setreg(wc, qrvmod, 0x10, (unsigned char)l); if (debug) dev_info(&wc->vb.pdev->dev, "@@@@@ setting reg 0x10 to %02x hex\n",(unsigned char)l); return; } -static void wctdm24xxp_get_fxs_regs(struct wctdm *wc, struct dahdi_chan *chan, +static void wctdm24xxp_get_fxs_regs(struct wctdm *wc, struct wctdm_module *mod, struct wctdm_regs *regs) { int x; + for (x = 0; x < NUM_INDIRECT_REGS; x++) - regs->indirect[x] = wctdm_proslic_getreg_indirect(wc, - chan->chanpos - 1, x); + regs->indirect[x] = wctdm_proslic_getreg_indirect(wc, mod, x); + for (x = 0; x < NUM_REGS; x++) - regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); + regs->direct[x] = wctdm_getreg(wc, mod, x); } -static void wctdm24xxp_get_fxo_regs(struct wctdm *wc, struct dahdi_chan *chan, +static void wctdm24xxp_get_fxo_regs(struct wctdm *wc, struct wctdm_module *mod, struct wctdm_regs *regs) { int x; for (x = 0; x < NUM_FXO_REGS; x++) - regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); + regs->direct[x] = wctdm_getreg(wc, mod, x); } -static void wctdm24xxp_get_qrv_regs(struct wctdm *wc, struct dahdi_chan *chan, +static void wctdm24xxp_get_qrv_regs(struct wctdm *wc, struct wctdm_module *mod, struct wctdm_regs *regs) { int x; for (x = 0; x < 0x32; x++) - regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); + regs->direct[x] = wctdm_getreg(wc, mod, x); } static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data) @@ -3074,7 +3243,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long fxs->ohttimer = x << 3; /* Active mode when idle */ - fxs->idletxhookstate = POLARITY_XOR(chan->chanpos - 1) ? + fxs->idletxhookstate = POLARITY_XOR(fxs) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; @@ -3082,7 +3251,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long ((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_ACTIVE_REV)) { x = set_lasttxhook_interruptible(fxs, - (POLARITY_XOR(chan->chanpos - 1) ? + (POLARITY_XOR(fxs) ? SLIC_LF_OHTRAN_REV : SLIC_LF_OHTRAN_FWD), &mod->sethook); @@ -3108,7 +3277,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long (__user void *)data, sizeof(fxs->vmwisetting))) return -EFAULT; - set_vmwi(wc, chan->chanpos - 1); + set_vmwi(wc, mod); break; case DAHDI_VMWI: if (mod->type != FXS) @@ -3118,17 +3287,17 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long if (0 > x) return -EFAULT; fxs->vmwi_active_messages = x; - set_vmwi(wc, chan->chanpos - 1); + set_vmwi(wc, mod); break; case WCTDM_GET_STATS: if (mod->type == FXS) { - stats.tipvolt = wctdm_getreg(wc, chan->chanpos - 1, 80) * -376; - stats.ringvolt = wctdm_getreg(wc, chan->chanpos - 1, 81) * -376; - stats.batvolt = wctdm_getreg(wc, chan->chanpos - 1, 82) * -376; + stats.tipvolt = wctdm_getreg(wc, mod, 80) * -376; + stats.ringvolt = wctdm_getreg(wc, mod, 81) * -376; + stats.batvolt = wctdm_getreg(wc, mod, 82) * -376; } else if (mod->type == FXO) { - stats.tipvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000; - stats.ringvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000; - stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000; + stats.tipvolt = (s8)wctdm_getreg(wc, mod, 29) * 1000; + stats.ringvolt = (s8)wctdm_getreg(wc, mod, 29) * 1000; + stats.batvolt = (s8)wctdm_getreg(wc, mod, 29) * 1000; } else return -EINVAL; if (copy_to_user((__user void *) data, &stats, sizeof(stats))) @@ -3141,11 +3310,11 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long return -ENOMEM; if (mod->type == FXS) - wctdm24xxp_get_fxs_regs(wc, chan, regs); + wctdm24xxp_get_fxs_regs(wc, mod, regs); else if (mod->type == QRV) - wctdm24xxp_get_qrv_regs(wc, chan, regs); + wctdm24xxp_get_qrv_regs(wc, mod, regs); else - wctdm24xxp_get_fxo_regs(wc, chan, regs); + wctdm24xxp_get_fxo_regs(wc, mod, regs); if (copy_to_user((__user void *)data, regs, sizeof(*regs))) { kfree(regs); @@ -3162,7 +3331,8 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long if (mod->type != FXS) return -EINVAL; dev_info(&wc->vb.pdev->dev, "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos); - wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val); + wctdm_proslic_setreg_indirect(wc, mod, regop.reg, + regop.val); } else { regop.val &= 0xff; if (regop.reg == LINE_STATE) { @@ -3170,7 +3340,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long fxs->lasttxhook = (regop.val & 0x0f) | SLIC_LF_OPPENDING; } dev_info(&wc->vb.pdev->dev, "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos); - wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val); + wctdm_setreg(wc, mod, regop.reg, regop.val); } break; case WCTDM_SET_ECHOTUNE: @@ -3180,17 +3350,17 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long if (mod->type == FXO) { /* Set the ACIM register */ - wctdm_setreg(wc, chan->chanpos - 1, 30, echoregs.acim); + wctdm_setreg(wc, mod, 30, echoregs.acim); /* Set the digital echo canceller registers */ - wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1); - wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2); - wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3); - wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4); - wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5); - wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6); - wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7); - wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8); + wctdm_setreg(wc, mod, 45, echoregs.coef1); + wctdm_setreg(wc, mod, 46, echoregs.coef2); + wctdm_setreg(wc, mod, 47, echoregs.coef3); + wctdm_setreg(wc, mod, 48, echoregs.coef4); + wctdm_setreg(wc, mod, 49, echoregs.coef5); + wctdm_setreg(wc, mod, 50, echoregs.coef6); + wctdm_setreg(wc, mod, 51, echoregs.coef7); + wctdm_setreg(wc, mod, 52, echoregs.coef8); dev_info(&wc->vb.pdev->dev, "-- Set echo registers successfully\n"); @@ -3204,7 +3374,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain))) return -EFAULT; - wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx); + wctdm_set_hwgain(wc, mod, hwgain.newgain, hwgain.tx); if (debug) dev_info(&wc->vb.pdev->dev, "Setting hwgain on channel %d to %d for %s direction\n", @@ -3232,7 +3402,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long fxs->reversepolarity = (x) ? 1 : 0; - if (POLARITY_XOR(chan->chanpos - 1)) { + if (POLARITY_XOR(fxs)) { fxs->idletxhookstate |= SLIC_LF_REVMASK; x = fxs->lasttxhook & SLIC_LF_SETMASK; x |= SLIC_LF_REVMASK; @@ -3449,8 +3619,8 @@ static int wctdm_close(struct dahdi_chan *chan) struct wctdm_module *const mod = &wc->mods[x]; if (FXS == mod->type) { mod->mod.fxs.idletxhookstate = - POLARITY_XOR(x) ? SLIC_LF_ACTIVE_REV : - SLIC_LF_ACTIVE_FWD; + POLARITY_XOR(&mod->mod.fxs) ? SLIC_LF_ACTIVE_REV : + SLIC_LF_ACTIVE_FWD; } else if (QRV == mod->type) { int qrvcard = x & 0xfc; @@ -3518,13 +3688,15 @@ static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig) dev_notice(&wc->vb.pdev->dev, "wctdm24xxp: Can't set tx state to %d\n", txsig); } } else if (mod->type == FXS) { - wctdm_fxs_hooksig(wc, chan->chanpos - 1, txsig); + wctdm_fxs_hooksig(wc, mod, txsig); } return 0; } static void wctdm_dacs_connect(struct wctdm *wc, int srccard, int dstcard) { + struct wctdm_module *const srcmod = &wc->mods[srccard]; + struct wctdm_module *const dstmod = &wc->mods[dstcard]; unsigned int type; if (wc->mods[dstcard].dacssrc > -1) { @@ -3545,71 +3717,88 @@ static void wctdm_dacs_connect(struct wctdm *wc, int srccard, int dstcard) "for card %d\n", dstcard); return; } - if (debug) - dev_info(&wc->vb.pdev->dev, "connect %d => %d\n", srccard, dstcard); - wc->mods[dstcard].dacssrc = srccard; + + if (debug) { + dev_info(&wc->vb.pdev->dev, + "connect %d => %d\n", srccard, dstcard); + } + + dstmod->dacssrc = srccard; /* make srccard transmit to srccard+24 on the TDM bus */ - if (wc->mods[srccard].type == FXS) { + if (srcmod->type == FXS) { /* proslic */ - wctdm_setreg(wc, srccard, PCM_XMIT_START_COUNT_LSB, ((srccard+24) * 8) & 0xff); - wctdm_setreg(wc, srccard, PCM_XMIT_START_COUNT_MSB, ((srccard+24) * 8) >> 8); - } else if (wc->mods[srccard].type == FXO) { - /* daa */ - wctdm_setreg(wc, srccard, 34, ((srccard+24) * 8) & 0xff); /* TX */ - wctdm_setreg(wc, srccard, 35, ((srccard+24) * 8) >> 8); /* TX */ + wctdm_setreg(wc, srcmod, PCM_XMIT_START_COUNT_LSB, + ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, srcmod, PCM_XMIT_START_COUNT_MSB, + ((srccard+24) * 8) >> 8); + } else if (srcmod->type == FXO) { + /* daa TX */ + wctdm_setreg(wc, srcmod, 34, ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, srcmod, 35, ((srccard+24) * 8) >> 8); } /* have dstcard receive from srccard+24 on the TDM bus */ - if (wc->mods[dstcard].type == FXS) { + if (dstmod->type == FXS) { /* proslic */ - wctdm_setreg(wc, dstcard, PCM_RCV_START_COUNT_LSB, ((srccard+24) * 8) & 0xff); - wctdm_setreg(wc, dstcard, PCM_RCV_START_COUNT_MSB, ((srccard+24) * 8) >> 8); - } else if (wc->mods[dstcard].type == FXO) { - /* daa */ - wctdm_setreg(wc, dstcard, 36, ((srccard+24) * 8) & 0xff); /* RX */ - wctdm_setreg(wc, dstcard, 37, ((srccard+24) * 8) >> 8); /* RX */ + wctdm_setreg(wc, dstmod, PCM_RCV_START_COUNT_LSB, + ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, dstmod, PCM_RCV_START_COUNT_MSB, + ((srccard+24) * 8) >> 8); + } else if (dstmod->type == FXO) { + /* daa RX */ + wctdm_setreg(wc, dstmod, 36, ((srccard+24) * 8) & 0xff); + wctdm_setreg(wc, dstmod, 37, ((srccard+24) * 8) >> 8); } - } static void wctdm_dacs_disconnect(struct wctdm *wc, int card) { struct wctdm_module *const mod = &wc->mods[card]; + struct wctdm_module *dacssrc; - if (mod->dacssrc > -1) { - if (debug) { - dev_info(&wc->vb.pdev->dev, - "wctdm_dacs_disconnect: restoring TX for %d " - "and RX for %d\n", mod->dacssrc, card); - } - - /* restore TX (source card) */ - if (wc->mods[mod->dacssrc].type == FXS) { - wctdm_setreg(wc, mod->dacssrc, PCM_XMIT_START_COUNT_LSB, - (wc->mods[card].dacssrc * 8) & 0xff); - wctdm_setreg(wc, mod->dacssrc, PCM_XMIT_START_COUNT_MSB, - (wc->mods[card].dacssrc * 8) >> 8); - } else if (wc->mods[mod->dacssrc].type == FXO) { - wctdm_setreg(wc, card, 34, (card * 8) & 0xff); - wctdm_setreg(wc, card, 35, (card * 8) >> 8); - } else { - dev_warn(&wc->vb.pdev->dev, "WARNING: wctdm_dacs_disconnect() called on unsupported modtype\n"); - } + if (mod->dacssrc <= -1) + return; - /* restore RX (this card) */ - if (FXS == mod->type) { - wctdm_setreg(wc, card, PCM_RCV_START_COUNT_LSB, (card * 8) & 0xff); - wctdm_setreg(wc, card, PCM_RCV_START_COUNT_MSB, (card * 8) >> 8); - } else if (FXO == mod->type) { - wctdm_setreg(wc, card, 36, (card * 8) & 0xff); - wctdm_setreg(wc, card, 37, (card * 8) >> 8); - } else { - dev_warn(&wc->vb.pdev->dev, "WARNING: wctdm_dacs_disconnect() called on unsupported modtype\n"); - } + dacssrc = &wc->mods[mod->dacssrc]; - mod->dacssrc = -1; + if (debug) { + dev_info(&wc->vb.pdev->dev, "wctdm_dacs_disconnect: " + "restoring TX for %d and RX for %d\n", + mod->dacssrc, card); + } + + /* restore TX (source card) */ + if (dacssrc->type == FXS) { + wctdm_setreg(wc, dacssrc, PCM_XMIT_START_COUNT_LSB, + (mod->dacssrc * 8) & 0xff); + wctdm_setreg(wc, dacssrc, PCM_XMIT_START_COUNT_MSB, + (mod->dacssrc * 8) >> 8); + } else if (dacssrc->type == FXO) { + wctdm_setreg(wc, mod, 34, (card * 8) & 0xff); + wctdm_setreg(wc, mod, 35, (card * 8) >> 8); + } else { + dev_warn(&wc->vb.pdev->dev, + "WARNING: wctdm_dacs_disconnect() called " + "on unsupported modtype\n"); + } + + /* restore RX (this card) */ + if (FXS == mod->type) { + wctdm_setreg(wc, mod, PCM_RCV_START_COUNT_LSB, + (card * 8) & 0xff); + wctdm_setreg(wc, mod, PCM_RCV_START_COUNT_MSB, + (card * 8) >> 8); + } else if (FXO == mod->type) { + wctdm_setreg(wc, mod, 36, (card * 8) & 0xff); + wctdm_setreg(wc, mod, 37, (card * 8) >> 8); + } else { + dev_warn(&wc->vb.pdev->dev, + "WARNING: wctdm_dacs_disconnect() called " + "on unsupported modtype\n"); } + + mod->dacssrc = -1; } static int wctdm_dacs(struct dahdi_chan *dst, struct dahdi_chan *src) @@ -3779,7 +3968,7 @@ static struct wctdm_span *wctdm_init_span(struct wctdm *wc, int spanno, int chan c = wctdm_init_chan(wc, s, chanoffset, x); if (!c) return NULL; - wc->chans[chanoffset + x] = c; + wc->mods[chanoffset + x].chan = c; s->span.chans[x] = &c->chan; } @@ -3787,9 +3976,9 @@ static struct wctdm_span *wctdm_init_span(struct wctdm *wc, int spanno, int chan s->span.irq = pdev->irq; if (digital_span) { - wc->chans[chanoffset + 0]->chan.sigcap = DAHDI_SIG_CLEAR; - wc->chans[chanoffset + 1]->chan.sigcap = DAHDI_SIG_CLEAR; - wc->chans[chanoffset + 2]->chan.sigcap = DAHDI_SIG_HARDHDLC; + wc->mods[chanoffset + 0].chan->chan.sigcap = DAHDI_SIG_CLEAR; + wc->mods[chanoffset + 1].chan->chan.sigcap = DAHDI_SIG_CLEAR; + wc->mods[chanoffset + 2].chan->chan.sigcap = DAHDI_SIG_HARDHDLC; } wc->spans[spanno] = s; @@ -3836,10 +4025,10 @@ static void wctdm_fixup_analog_span(struct wctdm *wc, int spanno) #ifdef DEBUG val = (digitalloopback) ? 0x30 : val; #endif - wctdm_setreg(wc, x, 33, val); + wctdm_setreg(wc, mod, 33, val); } else if (mod->type == FXS) { s->chans[y++]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR; - wctdm_setreg(wc, x, 1, + wctdm_setreg(wc, mod, 1, (should_set_alaw(wc) ? 0x20 : 0x28)); } else if (mod->type == QRV) { s->chans[y++]->sigcap = DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR; @@ -3964,20 +4153,23 @@ static int wctdm_identify_modules(struct wctdm *wc) if (fatal_signal_pending(current)) break; retry: - if (!(ret = wctdm_init_proslic(wc, x, 0, 0, sane))) { + if (!(ret = wctdm_init_proslic(wc, mod, 0, 0, sane))) { if (debug & DEBUG_CARD) { - readi = wctdm_getreg(wc,x,LOOP_I_LIMIT); - dev_info(&wc->vb.pdev->dev, "Proslic module %d loop current is %dmA\n", x, ((readi*3)+20)); + readi = wctdm_getreg(wc, mod, LOOP_I_LIMIT); + dev_info(&wc->vb.pdev->dev, + "Proslic module %d loop current " + "is %dmA\n", x, ((readi*3) + 20)); } - dev_info(&wc->vb.pdev->dev, "Port %d: Installed -- AUTO FXS/DPO\n", x + 1); + dev_info(&wc->vb.pdev->dev, + "Port %d: Installed -- AUTO FXS/DPO\n", x + 1); } else { if (ret != -2) { sane = 1; /* Init with Manual Calibration */ - if (!wctdm_init_proslic(wc, x, 0, 1, sane)) { + if (!wctdm_init_proslic(wc, mod, 0, 1, sane)) { if (debug & DEBUG_CARD) { - readi = wctdm_getreg(wc, x, LOOP_I_LIMIT); + readi = wctdm_getreg(wc, mod, LOOP_I_LIMIT); dev_info(&wc->vb.pdev->dev, "Proslic module %d loop current is %dmA\n", x, ((readi*3)+20)); } @@ -3986,7 +4178,7 @@ retry: dev_notice(&wc->vb.pdev->dev, "Port %d: FAILED FXS (%s)\n", x + 1, fxshonormode ? fxo_modes[_opermode].name : "FCC"); } - } else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) { + } else if (!(ret = wctdm_init_voicedaa(wc, mod, 0, 0, sane))) { dev_info(&wc->vb.pdev->dev, "Port %d: Installed -- AUTO FXO " "(%s mode)\n", x + 1, @@ -4061,9 +4253,9 @@ static void wctdm_back_out_gracefully(struct wctdm *wc) wc->spans[i] = NULL; } - for (i = 0; i < ARRAY_SIZE(wc->chans); ++i) { - kfree(wc->chans[i]); - wc->chans[i] = NULL; + for (i = 0; i < ARRAY_SIZE(wc->mods); ++i) { + kfree(wc->mods[i].chan); + wc->mods[i].chan = NULL; } spin_lock_irqsave(&wc->frame_list_lock, flags); @@ -4704,6 +4896,7 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) for (i = 0; i < NUM_MODULES; i++) { wc->mods[i].flags = wc->desc->flags; wc->mods[i].dacssrc = -1; + wc->mods[i].card = i; } /* Start the hardware processing. */ @@ -4816,13 +5009,13 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct wctdm_module *const mod = &wc->mods[i]; switch (mod->type) { case FXS: - wctdm_proslic_set_ts(wc, i, (digimods * 12) + i); + wctdm_proslic_set_ts(wc, mod, (digimods * 12) + i); break; case FXO: - wctdm_voicedaa_set_ts(wc, i, (digimods * 12) + i); + wctdm_voicedaa_set_ts(wc, mod, (digimods * 12) + i); break; case QRV: - wctdm_qrvdri_set_ts(wc, i, (digimods * 12) + i); + wctdm_qrvdri_set_ts(wc, mod, (digimods * 12) + i); break; default: break; |