summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-06-01 20:47:54 +0000
committerrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-06-01 20:47:54 +0000
commit881f04de9758b07a5695ec5aa3fcdd5db425d4fc (patch)
treebe43a96fee26226206f60657e399c8f840223562
parentf7ac289d679f87af35e7ca585d05c2d06577ac5b (diff)
add support for the 3215
git-svn-id: http://svn.digium.com/svn/zaptel/branches/v1-0@659 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xproslic.h1
-rwxr-xr-xwcfxs.c145
-rwxr-xr-xwcusb.c88
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;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {
+ if (indirect_regs[x].address == address) {
+ address = indirect_regs[x].altaddr;
+ break;
+ }
+ }
+ return address;
+}
+
static int wcfxs_proslic_setreg_indirect(struct wcfxs *wc, int card, unsigned char address, unsigned short data)
{
unsigned long flags;
int res = -1;
+ /* 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, 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;x<wc->cards;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;x<wc->cards;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;y<NUM_CARDS;y++)
+ wc->flags[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;