summaryrefslogtreecommitdiff
path: root/wctdm.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-02-11 23:46:23 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-02-11 23:46:23 +0000
commitbcba1a3e51ab2e88ac324ba7f4e7c5ae51bb3a88 (patch)
tree2b17b296e5ab683d0910650d29e0f2efa5b62fdd /wctdm.c
parentd5f969c40178901a4d809093f29b57757a2993d9 (diff)
Add support for 3215
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@584 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wctdm.c')
-rwxr-xr-xwctdm.c148
1 files changed, 90 insertions, 58 deletions
diff --git a/wctdm.c b/wctdm.c
index fa7aa9b..f28f4e7 100755
--- a/wctdm.c
+++ b/wctdm.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 wctdm {
int intcount;
int dead;
int pos;
- int flags;
+ int flags[NUM_CARDS];
int freeregion;
int alt;
int curcard;
@@ -658,10 +658,28 @@ static int __wait_access(struct wctdm *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 wctdm_proslic_setreg_indirect(struct wctdm *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)) {
__wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));
@@ -678,6 +696,12 @@ static int wctdm_proslic_getreg_indirect(struct wctdm *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)) {
__wctdm_setreg(wc, card, IAA, address);
@@ -723,7 +747,7 @@ static int wctdm_proslic_verify_indirect_regs(struct wctdm *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 );
@@ -1075,7 +1099,7 @@ static int wctdm_proslic_insane(struct wctdm *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;
@@ -1085,11 +1109,14 @@ static int wctdm_proslic_insane(struct wctdm *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 = wctdm_getreg(wc, card, 8);
if (blah != 0x2) {
printk("ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
@@ -1400,7 +1427,8 @@ static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual,
wctdm_getreg(wc, card, 11) >> 4,
(wctdm_getreg(wc, card, 13) >> 2) & 0xf);
/* Enable on-hook line monitor */
- wctdm_setreg(wc, card, 5, 0x08);
+ wctdm_setreg(wc, card, 5, 0x09 /* XXX 0x08 XXX */);
+ wc->mod.fxo.offhook[card] = 1;
return 0;
}
@@ -1555,6 +1583,7 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual,
if (fxo_modes[_opermode].ring_x)
wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x);
}
+ wctdm_setreg(wc,card,10,0);
if (lowpower)
wctdm_setreg(wc, card, 72, 0x10);
@@ -1582,6 +1611,7 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual,
return -1;
printk("Reducing ring power on slot %d (50V peak)\n", card + 1);
}
+ wctdm_setreg(wc, card, 64, 0x01);
return 0;
}
@@ -1797,8 +1827,8 @@ static int wctdm_initialize(struct wctdm *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;
}
@@ -1827,9 +1857,9 @@ static void wctdm_post_initialize(struct wctdm *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;
}
}
}
@@ -2011,6 +2041,7 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
struct wctdm *wc;
struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
int x;
+ int y;
static int initd_ifaces=0;
if(initd_ifaces){
@@ -2038,7 +2069,8 @@ static int __devinit wctdm_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, "wctdm"))
wc->freeregion = 1;