From 881f04de9758b07a5695ec5aa3fcdd5db425d4fc Mon Sep 17 00:00:00 2001 From: russell Date: Wed, 1 Jun 2005 20:47:54 +0000 Subject: add support for the 3215 git-svn-id: http://svn.digium.com/svn/zaptel/branches/v1-0@659 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- proslic.h | 1 + wcfxs.c | 145 +++++++++++++++++++++++++++++++++++++------------------------- wcusb.c | 88 +++++++++++++++++++------------------- 3 files changed, 133 insertions(+), 101 deletions(-) diff --git a/proslic.h b/proslic.h index 57548e3..933bd34 100755 --- a/proslic.h +++ b/proslic.h @@ -2,6 +2,7 @@ typedef struct { unsigned char address; + unsigned char altaddr; char *name; unsigned short initial; } alpha; diff --git a/wcfxs.c b/wcfxs.c index 8a21d9b..1d57c78 100755 --- a/wcfxs.c +++ b/wcfxs.c @@ -57,52 +57,52 @@ static int loopcurrent = 20; static alpha indirect_regs[] = { -{0,"DTMF_ROW_0_PEAK",0x55C2}, -{1,"DTMF_ROW_1_PEAK",0x51E6}, -{2,"DTMF_ROW2_PEAK",0x4B85}, -{3,"DTMF_ROW3_PEAK",0x4937}, -{4,"DTMF_COL1_PEAK",0x3333}, -{5,"DTMF_FWD_TWIST",0x0202}, -{6,"DTMF_RVS_TWIST",0x0202}, -{7,"DTMF_ROW_RATIO_TRES",0x0198}, -{8,"DTMF_COL_RATIO_TRES",0x0198}, -{9,"DTMF_ROW_2ND_ARM",0x0611}, -{10,"DTMF_COL_2ND_ARM",0x0202}, -{11,"DTMF_PWR_MIN_TRES",0x00E5}, -{12,"DTMF_OT_LIM_TRES",0x0A1C}, -{13,"OSC1_COEF",0x7B30}, -{14,"OSC1X",0x0063}, -{15,"OSC1Y",0x0000}, -{16,"OSC2_COEF",0x7870}, -{17,"OSC2X",0x007D}, -{18,"OSC2Y",0x0000}, -{19,"RING_V_OFF",0x0000}, -{20,"RING_OSC",0x7EF0}, -{21,"RING_X",0x0160}, -{22,"RING_Y",0x0000}, -{23,"PULSE_ENVEL",0x2000}, -{24,"PULSE_X",0x2000}, -{25,"PULSE_Y",0x0000}, -//{26,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower -{26,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower -{27,"XMIT_DIGITAL_GAIN",0x4000}, -//{27,"XMIT_DIGITAL_GAIN",0x2000}, -{28,"LOOP_CLOSE_TRES",0x1000}, -{29,"RING_TRIP_TRES",0x3600}, -{30,"COMMON_MIN_TRES",0x1000}, -{31,"COMMON_MAX_TRES",0x0200}, -{32,"PWR_ALARM_Q1Q2",0x07C0}, -{33,"PWR_ALARM_Q3Q4",0x2600}, -{34,"PWR_ALARM_Q5Q6",0x1B80}, -{35,"LOOP_CLOSURE_FILTER",0x8000}, -{36,"RING_TRIP_FILTER",0x0320}, -{37,"TERM_LP_POLE_Q1Q2",0x008C}, -{38,"TERM_LP_POLE_Q3Q4",0x0100}, -{39,"TERM_LP_POLE_Q5Q6",0x0010}, -{40,"CM_BIAS_RINGING",0x0C00}, -{41,"DCDC_MIN_V",0x0C00}, -{42,"DCDC_XTRA",0x1000}, -{43,"LOOP_CLOSE_TRES_LOW",0x1000}, +{0,255,"DTMF_ROW_0_PEAK",0x55C2}, +{1,255,"DTMF_ROW_1_PEAK",0x51E6}, +{2,255,"DTMF_ROW2_PEAK",0x4B85}, +{3,255,"DTMF_ROW3_PEAK",0x4937}, +{4,255,"DTMF_COL1_PEAK",0x3333}, +{5,255,"DTMF_FWD_TWIST",0x0202}, +{6,255,"DTMF_RVS_TWIST",0x0202}, +{7,255,"DTMF_ROW_RATIO_TRES",0x0198}, +{8,255,"DTMF_COL_RATIO_TRES",0x0198}, +{9,255,"DTMF_ROW_2ND_ARM",0x0611}, +{10,255,"DTMF_COL_2ND_ARM",0x0202}, +{11,255,"DTMF_PWR_MIN_TRES",0x00E5}, +{12,255,"DTMF_OT_LIM_TRES",0x0A1C}, +{13,0,"OSC1_COEF",0x7B30}, +{14,1,"OSC1X",0x0063}, +{15,2,"OSC1Y",0x0000}, +{16,3,"OSC2_COEF",0x7870}, +{17,4,"OSC2X",0x007D}, +{18,5,"OSC2Y",0x0000}, +{19,6,"RING_V_OFF",0x0000}, +{20,7,"RING_OSC",0x7EF0}, +{21,8,"RING_X",0x0160}, +{22,9,"RING_Y",0x0000}, +{23,255,"PULSE_ENVEL",0x2000}, +{24,255,"PULSE_X",0x2000}, +{25,255,"PULSE_Y",0x0000}, +//{26,13,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower +{26,13,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower +{27,14,"XMIT_DIGITAL_GAIN",0x4000}, +//{27,14,"XMIT_DIGITAL_GAIN",0x2000}, +{28,15,"LOOP_CLOSE_TRES",0x1000}, +{29,16,"RING_TRIP_TRES",0x3600}, +{30,17,"COMMON_MIN_TRES",0x1000}, +{31,18,"COMMON_MAX_TRES",0x0200}, +{32,19,"PWR_ALARM_Q1Q2",0x07C0}, +{33,20,"PWR_ALARM_Q3Q4",0x2600}, +{34,21,"PWR_ALARM_Q5Q6",0x1B80}, +{35,22,"LOOP_CLOSURE_FILTER",0x8000}, +{36,23,"RING_TRIP_FILTER",0x0320}, +{37,24,"TERM_LP_POLE_Q1Q2",0x008C}, +{38,25,"TERM_LP_POLE_Q3Q4",0x0100}, +{39,26,"TERM_LP_POLE_Q5Q6",0x0010}, +{40,27,"CM_BIAS_RINGING",0x0C00}, +{41,64,"DCDC_MIN_V",0x0C00}, +{42,255,"DCDC_XTRA",0x1000}, +{43,66,"LOOP_CLOSE_TRES_LOW",0x1000}, }; static struct fxo_mode { @@ -255,7 +255,7 @@ static struct fxo_mode { #define OHT_TIMER 6000 /* How long after RING to retain OHT */ -#define FLAG_DOUBLE_CLOCK (1 << 0) +#define FLAG_3215 (1 << 0) #define NUM_CARDS 4 @@ -283,7 +283,7 @@ struct wcfxs { int intcount; int dead; int pos; - int flags; + int flags[NUM_CARDS]; int freeregion; int alt; int curcard; @@ -657,10 +657,28 @@ static int __wait_access(struct wcfxs *wc, int card) return 0; } +static unsigned char translate_3215(unsigned char address) +{ + int x; + for (x=0;xflags[card] & FLAG_3215) { + address = translate_3215(address); + if (address == 255) + return 0; + } spin_lock_irqsave(&wc->lock, flags); if(!__wait_access(wc, card)) { __wcfxs_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF)); @@ -677,6 +695,12 @@ static int wcfxs_proslic_getreg_indirect(struct wcfxs *wc, int card, unsigned ch unsigned long flags; int res = -1; char *p=NULL; + /* Translate 3215 addresses */ + if (wc->flags[card] & FLAG_3215) { + address = translate_3215(address); + if (address == 255) + return 0; + } spin_lock_irqsave(&wc->lock, flags); if (!__wait_access(wc, card)) { __wcfxs_setreg(wc, card, IAA, address); @@ -722,7 +746,7 @@ static int wcfxs_proslic_verify_indirect_regs(struct wcfxs *wc, int card) } initial= indirect_regs[i].initial; - if ( j != initial ) + if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255))) { printk("!!!!!!! %s iREG %X = %X should be %X\n", indirect_regs[i].name,indirect_regs[i].address,j,initial ); @@ -1076,7 +1100,7 @@ static int wcfxs_proslic_insane(struct wcfxs *wc, int card) if (debug) printk("ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf)); -#if 0 +#if 0 if ((blah & 0x30) >> 4) { printk("ProSLIC on module %d is not a 3210.\n", card); return -1; @@ -1086,11 +1110,14 @@ static int wcfxs_proslic_insane(struct wcfxs *wc, int card) /* SLIC not loaded */ return -1; } - if ((blah & 0xf) < 3) { + if ((blah & 0xf) < 2) { printk("ProSLIC 3210 version %d is too old\n", blah & 0xf); return -1; } - + if ((blah & 0xf) == 2) { + /* ProSLIC 3215, not a 3210 */ + wc->flags[card] |= FLAG_3215; + } blah = wcfxs_getreg(wc, card, 8); if (blah != 0x2) { printk("ProSLIC on module %d insane (1) %d should be 2\n", card, blah); @@ -1400,7 +1427,6 @@ static int wcfxs_init_voicedaa(struct wcfxs *wc, int card, int fast, int manual, /* Enable on-hook line monitor */ wcfxs_setreg(wc, card, 5, 0x08); return 0; - } static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast, int manual, int sane) @@ -1577,6 +1603,7 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card, int fast, int manual, return -1; printk("Reducing ring power on slot %d (50V peak)\n", card + 1); } + wcfxs_setreg(wc, card, 64, 0x01); return 0; } @@ -1763,8 +1790,8 @@ static int wcfxs_initialize(struct wcfxs *wc) wc->span.deflaw = ZT_LAW_MULAW; for (x=0;xcards;x++) { sprintf(wc->chans[x].name, "WCTDM/%d/%d", wc->pos, x); - wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM; - wc->chans[x].sigcap |= ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF; + wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM | ZT_SIG_CLEAR; + wc->chans[x].sigcap |= ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF | ZT_SIG_CLEAR; wc->chans[x].chanpos = x+1; wc->chans[x].pvt = wc; } @@ -1793,9 +1820,9 @@ static void wcfxs_post_initialize(struct wcfxs *wc) for (x=0;xcards;x++) { if (wc->cardflag & (1 << x)) { if (wc->modtype[x] == MOD_TYPE_FXO) - wc->chans[x].sigcap = ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF; + wc->chans[x].sigcap = ZT_SIG_FXSKS | ZT_SIG_FXSLS | ZT_SIG_SF | ZT_SIG_CLEAR; else - wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM; + wc->chans[x].sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_SF | ZT_SIG_EM | ZT_SIG_CLEAR; } } } @@ -1977,6 +2004,7 @@ static int __devinit wcfxs_init_one(struct pci_dev *pdev, const struct pci_devic struct wcfxs *wc; struct wcfxs_desc *d = (struct wcfxs_desc *)ent->driver_data; int x; + int y; static int initd_ifaces=0; if(initd_ifaces){ @@ -2004,7 +2032,8 @@ static int __devinit wcfxs_init_one(struct pci_dev *pdev, const struct pci_devic wc->dev = pdev; wc->pos = x; wc->variety = d->name; - wc->flags = d->flags; + for (y=0;yflags[y] = d->flags; /* Keep track of whether we need to free the region */ if (request_region(wc->ioaddr, 0xff, "wcfxs")) wc->freeregion = 1; diff --git a/wcusb.c b/wcusb.c index 7192070..e957cf8 100755 --- a/wcusb.c +++ b/wcusb.c @@ -75,50 +75,52 @@ static int writeProSlicInDirectReg(struct usb_device *dev, unsigned char address static alpha indirect_regs[] = { -{0,"DTMF_ROW_0_PEAK",0x55C2}, -{1,"DTMF_ROW_1_PEAK",0x51E6}, -{2,"DTMF_ROW2_PEAK",0x4B85}, -{3,"DTMF_ROW3_PEAK",0x4937}, -{4,"DTMF_COL1_PEAK",0x3333}, -{5,"DTMF_FWD_TWIST",0x0202}, -{6,"DTMF_RVS_TWIST",0x0202}, -{7,"DTMF_ROW_RATIO_TRES",0x0198}, -{8,"DTMF_COL_RATIO_TRES",0x0198}, -{9,"DTMF_ROW_2ND_ARM",0x0611}, -{10,"DTMF_COL_2ND_ARM",0x0202}, -{11,"DTMF_PWR_MIN_TRES",0x00E5}, -{12,"DTMF_OT_LIM_TRES",0x0A1C}, -{13,"OSC1_COEF",0x6D40}, -{14,"OSC1X",0x0470}, -{15,"OSC1Y",0x0000}, -{16,"OSC2_COEF",0x4A80}, -{17,"OSC2X",0x0830}, -{18,"OSC2Y",0x0000}, -{19,"RING_V_OFF",0x0000}, -{20,"RING_OSC",0x7EF0}, -{21,"RING_X",0x0160}, -{22,"RING_Y",0x0000}, -{23,"PULSE_ENVEL",0x2000}, -{24,"PULSE_X",0x2000}, -{25,"PULSE_Y",0x0000}, +{0,255,"DTMF_ROW_0_PEAK",0x55C2}, +{1,255,"DTMF_ROW_1_PEAK",0x51E6}, +{2,255,"DTMF_ROW2_PEAK",0x4B85}, +{3,255,"DTMF_ROW3_PEAK",0x4937}, +{4,255,"DTMF_COL1_PEAK",0x3333}, +{5,255,"DTMF_FWD_TWIST",0x0202}, +{6,255,"DTMF_RVS_TWIST",0x0202}, +{7,255,"DTMF_ROW_RATIO_TRES",0x0198}, +{8,255,"DTMF_COL_RATIO_TRES",0x0198}, +{9,255,"DTMF_ROW_2ND_ARM",0x0611}, +{10,255,"DTMF_COL_2ND_ARM",0x0202}, +{11,255,"DTMF_PWR_MIN_TRES",0x00E5}, +{12,255,"DTMF_OT_LIM_TRES",0x0A1C}, +{13,0,"OSC1_COEF",0x7B30}, +{14,1,"OSC1X",0x0063}, +{15,2,"OSC1Y",0x0000}, +{16,3,"OSC2_COEF",0x7870}, +{17,4,"OSC2X",0x007D}, +{18,5,"OSC2Y",0x0000}, +{19,6,"RING_V_OFF",0x0000}, +{20,7,"RING_OSC",0x7EF0}, +{21,8,"RING_X",0x0160}, +{22,9,"RING_Y",0x0000}, +{23,255,"PULSE_ENVEL",0x2000}, +{24,255,"PULSE_X",0x2000}, +{25,255,"PULSE_Y",0x0000}, //{26,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower -{26,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower -{27,"XMIT_DIGITAL_GAIN",0x8000}, -{28,"LOOP_CLOSE_TRES",0x1000}, -{29,"RING_TRIP_TRES",0x3600}, -{30,"COMMON_MIN_TRES",0x1000}, -{31,"COMMON_MAX_TRES",0x0200}, -{32,"PWR_ALARM_Q1Q2",0x0550}, -{33,"PWR_ALARM_Q3Q4",0x2600}, -{34,"PWR_ALARM_Q5Q6",0x1B80}, -{35,"LOOP_CLOSURE_FILTER",0x8000}, -{36,"RING_TRIP_FILTER",0x0320}, -{37,"TERM_LP_POLE_Q1Q2",0x0100}, -{38,"TERM_LP_POLE_Q3Q4",0x0100}, -{39,"TERM_LP_POLE_Q5Q6",0x0010}, -{40,"CM_BIAS_RINGING",0x0C00}, -{41,"DCDC_MIN_V",0x0C00}, -{42,"DCDC_XTRA",0x1000}, +{26,13,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower +{27,14,"XMIT_DIGITAL_GAIN",0x4000}, +//{27,"XMIT_DIGITAL_GAIN",0x2000}, +{28,15,"LOOP_CLOSE_TRES",0x1000}, +{29,16,"RING_TRIP_TRES",0x3600}, +{30,17,"COMMON_MIN_TRES",0x1000}, +{31,18,"COMMON_MAX_TRES",0x0200}, +{32,19,"PWR_ALARM_Q1Q2",0x07C0}, +{33,20,"PWR_ALARM_Q3Q4",0x2600}, +{34,21,"PWR_ALARM_Q5Q6",0x1B80}, +{35,22,"LOOP_CLOSURE_FILTER",0x8000}, +{36,23,"RING_TRIP_FILTER",0x0320}, +{37,24,"TERM_LP_POLE_Q1Q2",0x008C}, +{38,25,"TERM_LP_POLE_Q3Q4",0x0100}, +{39,26,"TERM_LP_POLE_Q5Q6",0x0010}, +{40,27,"CM_BIAS_RINGING",0x0C00}, +{41,64,"DCDC_MIN_V",0x0C00}, +{42,255,"DCDC_XTRA",0x1000}, +{43,66,"LOOP_CLOSE_TRES_LOW",0x1000}, }; static int debug = 0; -- cgit v1.2.3