summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-10-04 20:46:11 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-10-04 20:46:11 +0000
commit4a37f022ab8af3d8a9412b85e220956bcf0d7ccb (patch)
tree010609731bfabfbd50ebddd929acd7452cf6093f
parent47bb8692285b72530c8bfdfe0ce777aa8b594592 (diff)
Version 0.3.1 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@114 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xtor2.c83
-rwxr-xr-xwcfxs.c164
-rwxr-xr-xwctdm.c164
3 files changed, 207 insertions, 204 deletions
diff --git a/tor2.c b/tor2.c
index 8e1879a..cb93702 100755
--- a/tor2.c
+++ b/tor2.c
@@ -83,6 +83,7 @@ struct tor2 {
int alarmtimer[4]; /* Alarm timer */
char *type; /* Type of tormenta 2 card */
int irq; /* IRQ used by device */
+ int order; /* Order */
int flags; /* Device flags */
unsigned long plx_region; /* phy addr of PCI9030 registers */
unsigned long plx_len; /* length of PLX window */
@@ -133,6 +134,7 @@ static void tor2_tasklet(unsigned long data);
#define CTLREG 0x401
#define LEDREG 0x402
#define STATREG 0x400
+#define SWREG 0x401
#define INTENA (1 + ((loopback & 3) << 5))
#define OUTBIT (2 + ((loopback & 3) << 5))
@@ -159,6 +161,7 @@ struct tor2 *cards[MAX_TOR_CARDS];
static int debug;
static int loopback;
+static int highestorder;
static void set_clear(struct tor2 *tor);
static int tor2_startup(struct zt_span *span);
@@ -285,9 +288,41 @@ static void init_spans(struct tor2 *tor)
}
}
+static int __devinit tor2_launch(struct tor2 *tor)
+{
+ printk("tor2: Launching card: %d\n", tor->order);
+ if (zt_register(&tor->spans[0], 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", tor->spans[0].name);
+ return -1;
+ }
+ if (zt_register(&tor->spans[1], 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", tor->spans[1].name);
+ zt_unregister(&tor->spans[0]);
+ return -1;
+ }
+ if (zt_register(&tor->spans[2], 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", tor->spans[2].name);
+ zt_unregister(&tor->spans[0]);
+ zt_unregister(&tor->spans[1]);
+ return -1;
+ }
+ if (zt_register(&tor->spans[3], 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", tor->spans[3].name);
+ zt_unregister(&tor->spans[0]);
+ zt_unregister(&tor->spans[1]);
+ zt_unregister(&tor->spans[2]);
+ return -1;
+ }
+ tor->plx[INTCSR] = cpu_to_le16(PLX_INTENA); /* enable PLX interrupt */
+#ifdef ENABLE_TASKLETS
+ tasklet_init(&tor->tor2_tlet, tor2_tasklet, (unsigned long)tor);
+#endif
+ return 0;
+}
+
static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res,x;
+ int res,x,f;
struct tor2 *tor;
unsigned long endjif;
volatile unsigned long *gpdata_io;
@@ -442,6 +477,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
tor->mem8[LEDREG] = 0;
for(x = 0; x < 256; x++) tor->mem32[x] = 0x7f7f7f7f;
+
if (request_irq(tor->irq, tor2_intr, SA_INTERRUPT | SA_SHIRQ, "tor2", tor)) {
printk(KERN_ERR "Unable to request tormenta IRQ %d\n", tor->irq);
goto err_out_release_all;
@@ -458,32 +494,27 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
}
init_spans(tor);
- if (zt_register(&tor->spans[0], 0)) {
- printk(KERN_ERR "Unable to register span %s\n", tor->spans[0].name);
- goto err_out_release_all;
- }
- if (zt_register(&tor->spans[1], 0)) {
- printk(KERN_ERR "Unable to register span %s\n", tor->spans[1].name);
- zt_unregister(&tor->spans[0]);
- goto err_out_release_all;
- }
- if (zt_register(&tor->spans[2], 0)) {
- printk(KERN_ERR "Unable to register span %s\n", tor->spans[2].name);
- zt_unregister(&tor->spans[0]);
- zt_unregister(&tor->spans[1]);
- goto err_out_release_all;
- }
- if (zt_register(&tor->spans[3], 0)) {
- printk(KERN_ERR "Unable to register span %s\n", tor->spans[3].name);
- zt_unregister(&tor->spans[0]);
- zt_unregister(&tor->spans[1]);
- zt_unregister(&tor->spans[2]);
- goto err_out_release_all;
+ tor->order = tor->mem8[SWREG];
+ printk("Detected Card number: %d\n", tor->order);
+
+ /* Launch cards as appropriate */
+ x = 0;
+ for(;;) {
+ /* Find a card to activate */
+ f = 0;
+ for (x=0;cards[x];x++) {
+ if (cards[x]->order == highestorder) {
+ tor2_launch(cards[x]);
+ f = 1;
+ }
+ }
+ /* If we found at least one, increment the highest order and search again, otherwise stop */
+ if (f)
+ highestorder++;
+ else
+ break;
}
- tor->plx[INTCSR] = cpu_to_le16(PLX_INTENA); /* enable PLX interrupt */
-#ifdef ENABLE_TASKLETS
- tasklet_init(&tor->tor2_tlet, tor2_tasklet, (unsigned long)tor);
-#endif
+
return 0;
err_out_release_all:
diff --git a/wcfxs.c b/wcfxs.c
index 228cfcc..610d038 100755
--- a/wcfxs.c
+++ b/wcfxs.c
@@ -63,10 +63,10 @@ static alpha indirect_regs[] =
{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},
+{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},
@@ -83,7 +83,6 @@ static alpha indirect_regs[] =
{41,"DCDC_MIN_V",0x0C00},
{42,"DCDC_XTRA",0x1000},
{43,"LOOP_CLOSE_TRES_LOW",0x1000},
-{97,"RCV_FLTR", 0}
};
#ifdef STANDALONE_ZAPATA
@@ -120,7 +119,6 @@ static alpha indirect_regs[] =
#define WC_TEST 0x1
#define WC_CS 0x2
#define WC_VER 0x3
-#define WC_LEDS 0x4
#define BIT_CS (1 << 2)
#define BIT_SCLK (1 << 3)
@@ -152,6 +150,7 @@ struct wcfxs {
int alt;
int curcard;
int cards;
+ int cardflag; /* Bit-map of present cards */
spinlock_t lock;
/* Receive hook state and debouncing */
@@ -197,12 +196,14 @@ static inline void wcfxs_transmitprep(struct wcfxs *wc, unsigned char ints)
for (x=0;x<ZT_CHUNKSIZE;x++) {
/* Send a sample, as a 32-bit word */
- writechunk[x] = (wc->chans[0].writechunk[x] << 24);
- if (wc->cards > 1)
+ writechunk[x] = 0;
+ if (wc->cardflag & (1 << 0))
+ writechunk[x] |= (wc->chans[0].writechunk[x] << 24);
+ if (wc->cardflag & (1 << 1))
writechunk[x] |= (wc->chans[1].writechunk[x] << 16);
- if (wc->cards > 2)
+ if (wc->cardflag & (1 << 2))
writechunk[x] |= (wc->chans[2].writechunk[x] << 8);
- if (wc->cards > 3)
+ if (wc->cardflag & (1 << 3))
writechunk[x] |= (wc->chans[3].writechunk[x]);
}
@@ -220,17 +221,20 @@ static inline void wcfxs_receiveprep(struct wcfxs *wc, unsigned char ints)
/* Read is not at interrupt address. Valid data is available at normal offset */
readchunk = wc->readchunk;
for (x=0;x<ZT_CHUNKSIZE;x++) {
- wc->chans[0].readchunk[x] = (readchunk[x] >> 24) & 0xff;
- if (wc->cards > 1)
+ if (wc->cardflag & (1 << 0))
+ wc->chans[0].readchunk[x] = (readchunk[x] >> 24) & 0xff;
+ if (wc->cardflag & (1 << 1))
wc->chans[1].readchunk[x] = (readchunk[x] >> 16) & 0xff;
- if (wc->cards > 2)
+ if (wc->cardflag & (1 << 2))
wc->chans[2].readchunk[x] = (readchunk[x] >> 8) & 0xff;
- if (wc->cards > 3)
+ if (wc->cardflag & (1 << 3))
wc->chans[3].readchunk[x] = (readchunk[x]) & 0xff;
}
/* XXX We're wasting 8 taps. We should get closer :( */
- for (x=0;x<wc->cards;x++)
- zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk);
+ for (x=0;x<wc->cards;x++) {
+ if (wc->cardflag & (1 << x))
+ zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk);
+ }
zt_receive(&wc->span);
}
@@ -240,16 +244,11 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct wcfxs *wc = dev_id;
unsigned char ints;
- static int p=0;
+ int x;
ints = inb(wc->ioaddr + WC_INTSTAT);
outb(ints, wc->ioaddr + WC_INTSTAT);
- if (!p) {
- printk("Interrupt!\n");
- p++;
- }
-
if (!ints)
return;
@@ -266,8 +265,9 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (ints & 0x0f) {
wc->intcount++;
- if ((wc->intcount % 10) < wc->cards) {
- wcfxs_check_hook(wc, wc->intcount % 10);
+ x = wc->intcount % 10;
+ if ((x < wc->cards) && (wc->cardflag & (1 << x))) {
+ wcfxs_check_hook(wc, x);
}
wcfxs_receiveprep(wc, ints);
wcfxs_transmitprep(wc, ints);
@@ -281,10 +281,6 @@ static inline void write_8bits(struct wcfxs *wc, unsigned char bits)
int x;
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
wc->ios &= ~BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
for (x=0;x<8;x++) {
@@ -295,25 +291,14 @@ static inline void write_8bits(struct wcfxs *wc, unsigned char bits)
wc->ios &= ~BIT_SDI;
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Now raise SCLK high again and repeat */
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
bits <<= 1;
}
/* Finally raise CS back high again */
wc->ios |= BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
}
static inline unsigned char read_8bits(struct wcfxs *wc)
@@ -322,17 +307,14 @@ static inline unsigned char read_8bits(struct wcfxs *wc)
int x;
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Drop chip select */
wc->ios &= ~BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
for (x=0;x<8;x++) {
res <<= 1;
/* Get SCLK */
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Read back the value */
c = inb(wc->ioaddr + WC_AUXR);
if (c & BIT_SDO)
@@ -340,16 +322,10 @@ static inline unsigned char read_8bits(struct wcfxs *wc)
/* Now raise SCLK high again */
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
}
/* Finally raise CS back high again */
wc->ios |= BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
@@ -474,9 +450,9 @@ static int wcfxs_init_indirect_regs(struct wcfxs *wc, int card)
{
unsigned char i;
- for (i=0; i<43; i++)
+ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
{
- if(wcfxs_setreg_indirect(wc, card, i,indirect_regs[i].initial))
+ if(wcfxs_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
return -1;
}
@@ -489,9 +465,9 @@ static int wcfxs_verify_indirect_regs(struct wcfxs *wc, int card)
unsigned short i, initial;
int j;
- for (i=0; i<43; i++)
+ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
{
- if((j = wcfxs_getreg_indirect(wc, card, (unsigned char) i)) < 0) {
+ if((j = wcfxs_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
printk("Failed to read indirect register %d\n", i);
return -1;
}
@@ -500,7 +476,7 @@ static int wcfxs_verify_indirect_regs(struct wcfxs *wc, int card)
if ( j != initial )
{
printk("!!!!!!! %s iREG %X = %X should be %X\n",
- indirect_regs[i].name,i,j,initial );
+ indirect_regs[i].name,indirect_regs[i].address,j,initial );
passed = 0;
}
}
@@ -529,6 +505,10 @@ static int wcfxs_proslic_insane(struct wcfxs *wc, int card)
return -1;
}
#endif
+ if ((blah & 0xf) == 0) {
+ /* SLIC not loaded */
+ return -1;
+ }
if ((blah & 0xf) < 3) {
printk("ProSLIC 3210 version %d is too old\n", blah & 0xf);
return -1;
@@ -769,9 +749,9 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
wcfxs_setreg(wc, card, 1, 0x28);
// U-Law 8-bit interface
- wcfxs_setreg(wc, card, 2, 0); // Tx Start count low byte 0
+ wcfxs_setreg(wc, card, 2, card * 8); // Tx Start count low byte 0
wcfxs_setreg(wc, card, 3, 0); // Tx Start count high byte 0
- wcfxs_setreg(wc, card, 4, 0); // Rx Start count low byte 0
+ wcfxs_setreg(wc, card, 4, card * 8); // Rx Start count low byte 0
wcfxs_setreg(wc, card, 5, 0); // Rx Start count high byte 0
wcfxs_setreg(wc, card, 18, 0xff); // clear all interrupt
wcfxs_setreg(wc, card, 19, 0xff);
@@ -793,8 +773,6 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
wcfxs_setreg(wc, card, 1, 0x08);
#endif
- printk("Loopback: %02x\n", wcfxs_getreg(wc, card, 8));
-
#ifdef BOOST_RINGER
/* Beef up Ringing voltage to 89V */
if (wcfxs_setreg_indirect(wc, card, 23, 0x1d1))
@@ -815,40 +793,44 @@ static inline void wcfxs_check_hook(struct wcfxs *wc, int card)
hook = (res & 1);
if (hook != wc->lastrxhook[card]) {
/* Reset the debounce */
- wc->debounce[card] = 50;
+ wc->debounce[card] = 10;
#if 0
printk("Resetting debounce card %d hook %d, %d\n", card, hook, wc->debounce[card]);
#endif
} else {
- if (wc->debounce[card] > -1) {
+ if (wc->debounce[card] > 0) {
wc->debounce[card]--;
#if 0
printk("Sustaining hook %d, %d\n", hook, wc->debounce[card]);
#endif
- }
- }
- wc->lastrxhook[card] = hook;
- if (!wc->debounce[card]) {
+ if (!wc->debounce[card]) {
#if 0
- printk("Counted down debounce, newhook: %d...\n", hook);
+ printk("Counted down debounce, newhook: %d...\n", hook);
#endif
- wc->debouncehook[card] = hook;
+ wc->debouncehook[card] = hook;
+ }
+ if (!wc->oldrxhook[card] && wc->debouncehook[card]) {
+ /* Off hook */
+#if 1
+ if (debug)
+#endif
+ printk("wcfxs: Card %d Going off hook\n", card);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
+ wc->oldrxhook[card] = 1;
+
+ } else if (wc->oldrxhook[card] && !wc->debouncehook[card]) {
+ /* On hook */
+#if 1
+ if (debug)
+#endif
+ printk("wcfxs: Card %d Going on hook\n", card);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);
+ wc->oldrxhook[card] = 0;
+ }
+ }
}
+ wc->lastrxhook[card] = hook;
- if (!wc->oldrxhook[card] && wc->debouncehook[card]) {
- /* Off hook */
- if (debug)
- printk("wcfxs: Card %d Going off hook\n", card);
- zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
- wc->oldrxhook[card] = 1;
-
- } else if (wc->oldrxhook[card] && !wc->debouncehook[card]) {
- /* On hook */
- if (debug)
- printk("wcfxs: Card %d Going on hook\n", card);
- zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);
- wc->oldrxhook[card] = 0;
- }
}
@@ -884,6 +866,8 @@ static int wcfxs_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long dat
static int wcfxs_open(struct zt_chan *chan)
{
struct wcfxs *wc = chan->pvt;
+ if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
+ return -ENODEV;
if (wc->dead)
return -ENODEV;
wc->usecount++;
@@ -945,7 +929,7 @@ static int wcfxs_initialize(struct wcfxs *wc)
int x;
/* Zapata stuff */
sprintf(wc->span.name, "WCFXS/%d", wc->pos);
- sprintf(wc->span.desc, "%s Board %d, %d modules\n", wc->variety, wc->pos + 1, wc->cards);
+ sprintf(wc->span.desc, "%s Board %d\n", wc->variety, wc->pos + 1);
wc->span.deflaw = ZT_LAW_MULAW;
for (x=0;x<wc->cards;x++) {
sprintf(wc->chans[x].name, "WCFXS/%d/%d", wc->pos, x);
@@ -999,11 +983,8 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
return -1;
}
/* Go to half-duty FSYNC */
- wcfxs_setcreg(wc, WC_SYNC, 0x1);
+ wcfxs_setcreg(wc, WC_SYNC, 0x00);
y = wcfxs_getcreg(wc, WC_SYNC);
- printk("SYNC is %d\n", y);
- /* Turn off LED's */
- wcfxs_setcreg(wc, WC_LEDS, 0xff);
} else {
printk("No freshmaker chip\n");
}
@@ -1051,11 +1032,16 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
while(jiffies - oldjiffies < (HZ / 4) + 1);
for (x=0;x<wc->cards;x++) {
- if (wcfxs_init_proslic(wc, x)) {
- printk("Error initializing card %d\n", x);
- return -1;
- }
+ if (!wcfxs_init_proslic(wc, x)) {
+ printk("Module %d: Initialized\n", x);
+ wc->cardflag |= (1 << x);
+ } else
+ printk("Module %d: Not installed\n", x);
}
+ /* Return error if nothing initialized okay. */
+ if (!wc->cardflag)
+ return -1;
+ wcfxs_setcreg(wc, WC_SYNC, wc->cardflag << 1);
return 0;
}
@@ -1116,7 +1102,7 @@ static int __devinit wcfxs_init_one(struct pci_dev *pdev, const struct pci_devic
memset(wc, 0, sizeof(struct wcfxs));
spin_lock_init(&wc->lock);
wc->curcard = -1;
- wc->cards = 1;
+ wc->cards = 4;
wc->ioaddr = pci_resource_start(pdev, 0);
wc->dev = pdev;
wc->pos = x;
diff --git a/wctdm.c b/wctdm.c
index 228cfcc..610d038 100755
--- a/wctdm.c
+++ b/wctdm.c
@@ -63,10 +63,10 @@ static alpha indirect_regs[] =
{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},
+{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},
@@ -83,7 +83,6 @@ static alpha indirect_regs[] =
{41,"DCDC_MIN_V",0x0C00},
{42,"DCDC_XTRA",0x1000},
{43,"LOOP_CLOSE_TRES_LOW",0x1000},
-{97,"RCV_FLTR", 0}
};
#ifdef STANDALONE_ZAPATA
@@ -120,7 +119,6 @@ static alpha indirect_regs[] =
#define WC_TEST 0x1
#define WC_CS 0x2
#define WC_VER 0x3
-#define WC_LEDS 0x4
#define BIT_CS (1 << 2)
#define BIT_SCLK (1 << 3)
@@ -152,6 +150,7 @@ struct wcfxs {
int alt;
int curcard;
int cards;
+ int cardflag; /* Bit-map of present cards */
spinlock_t lock;
/* Receive hook state and debouncing */
@@ -197,12 +196,14 @@ static inline void wcfxs_transmitprep(struct wcfxs *wc, unsigned char ints)
for (x=0;x<ZT_CHUNKSIZE;x++) {
/* Send a sample, as a 32-bit word */
- writechunk[x] = (wc->chans[0].writechunk[x] << 24);
- if (wc->cards > 1)
+ writechunk[x] = 0;
+ if (wc->cardflag & (1 << 0))
+ writechunk[x] |= (wc->chans[0].writechunk[x] << 24);
+ if (wc->cardflag & (1 << 1))
writechunk[x] |= (wc->chans[1].writechunk[x] << 16);
- if (wc->cards > 2)
+ if (wc->cardflag & (1 << 2))
writechunk[x] |= (wc->chans[2].writechunk[x] << 8);
- if (wc->cards > 3)
+ if (wc->cardflag & (1 << 3))
writechunk[x] |= (wc->chans[3].writechunk[x]);
}
@@ -220,17 +221,20 @@ static inline void wcfxs_receiveprep(struct wcfxs *wc, unsigned char ints)
/* Read is not at interrupt address. Valid data is available at normal offset */
readchunk = wc->readchunk;
for (x=0;x<ZT_CHUNKSIZE;x++) {
- wc->chans[0].readchunk[x] = (readchunk[x] >> 24) & 0xff;
- if (wc->cards > 1)
+ if (wc->cardflag & (1 << 0))
+ wc->chans[0].readchunk[x] = (readchunk[x] >> 24) & 0xff;
+ if (wc->cardflag & (1 << 1))
wc->chans[1].readchunk[x] = (readchunk[x] >> 16) & 0xff;
- if (wc->cards > 2)
+ if (wc->cardflag & (1 << 2))
wc->chans[2].readchunk[x] = (readchunk[x] >> 8) & 0xff;
- if (wc->cards > 3)
+ if (wc->cardflag & (1 << 3))
wc->chans[3].readchunk[x] = (readchunk[x]) & 0xff;
}
/* XXX We're wasting 8 taps. We should get closer :( */
- for (x=0;x<wc->cards;x++)
- zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk);
+ for (x=0;x<wc->cards;x++) {
+ if (wc->cardflag & (1 << x))
+ zt_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->chans[x].writechunk);
+ }
zt_receive(&wc->span);
}
@@ -240,16 +244,11 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct wcfxs *wc = dev_id;
unsigned char ints;
- static int p=0;
+ int x;
ints = inb(wc->ioaddr + WC_INTSTAT);
outb(ints, wc->ioaddr + WC_INTSTAT);
- if (!p) {
- printk("Interrupt!\n");
- p++;
- }
-
if (!ints)
return;
@@ -266,8 +265,9 @@ static void wcfxs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (ints & 0x0f) {
wc->intcount++;
- if ((wc->intcount % 10) < wc->cards) {
- wcfxs_check_hook(wc, wc->intcount % 10);
+ x = wc->intcount % 10;
+ if ((x < wc->cards) && (wc->cardflag & (1 << x))) {
+ wcfxs_check_hook(wc, x);
}
wcfxs_receiveprep(wc, ints);
wcfxs_transmitprep(wc, ints);
@@ -281,10 +281,6 @@ static inline void write_8bits(struct wcfxs *wc, unsigned char bits)
int x;
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
wc->ios &= ~BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
for (x=0;x<8;x++) {
@@ -295,25 +291,14 @@ static inline void write_8bits(struct wcfxs *wc, unsigned char bits)
wc->ios &= ~BIT_SDI;
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Now raise SCLK high again and repeat */
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
bits <<= 1;
}
/* Finally raise CS back high again */
wc->ios |= BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
}
static inline unsigned char read_8bits(struct wcfxs *wc)
@@ -322,17 +307,14 @@ static inline unsigned char read_8bits(struct wcfxs *wc)
int x;
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Drop chip select */
wc->ios &= ~BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
for (x=0;x<8;x++) {
res <<= 1;
/* Get SCLK */
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
/* Read back the value */
c = inb(wc->ioaddr + WC_AUXR);
if (c & BIT_SDO)
@@ -340,16 +322,10 @@ static inline unsigned char read_8bits(struct wcfxs *wc)
/* Now raise SCLK high again */
wc->ios |= BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
}
/* Finally raise CS back high again */
wc->ios |= BIT_CS;
outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
- outb(wc->ios, wc->ioaddr + WC_AUXD);
wc->ios &= ~BIT_SCLK;
outb(wc->ios, wc->ioaddr + WC_AUXD);
@@ -474,9 +450,9 @@ static int wcfxs_init_indirect_regs(struct wcfxs *wc, int card)
{
unsigned char i;
- for (i=0; i<43; i++)
+ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
{
- if(wcfxs_setreg_indirect(wc, card, i,indirect_regs[i].initial))
+ if(wcfxs_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
return -1;
}
@@ -489,9 +465,9 @@ static int wcfxs_verify_indirect_regs(struct wcfxs *wc, int card)
unsigned short i, initial;
int j;
- for (i=0; i<43; i++)
+ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
{
- if((j = wcfxs_getreg_indirect(wc, card, (unsigned char) i)) < 0) {
+ if((j = wcfxs_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
printk("Failed to read indirect register %d\n", i);
return -1;
}
@@ -500,7 +476,7 @@ static int wcfxs_verify_indirect_regs(struct wcfxs *wc, int card)
if ( j != initial )
{
printk("!!!!!!! %s iREG %X = %X should be %X\n",
- indirect_regs[i].name,i,j,initial );
+ indirect_regs[i].name,indirect_regs[i].address,j,initial );
passed = 0;
}
}
@@ -529,6 +505,10 @@ static int wcfxs_proslic_insane(struct wcfxs *wc, int card)
return -1;
}
#endif
+ if ((blah & 0xf) == 0) {
+ /* SLIC not loaded */
+ return -1;
+ }
if ((blah & 0xf) < 3) {
printk("ProSLIC 3210 version %d is too old\n", blah & 0xf);
return -1;
@@ -769,9 +749,9 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
wcfxs_setreg(wc, card, 1, 0x28);
// U-Law 8-bit interface
- wcfxs_setreg(wc, card, 2, 0); // Tx Start count low byte 0
+ wcfxs_setreg(wc, card, 2, card * 8); // Tx Start count low byte 0
wcfxs_setreg(wc, card, 3, 0); // Tx Start count high byte 0
- wcfxs_setreg(wc, card, 4, 0); // Rx Start count low byte 0
+ wcfxs_setreg(wc, card, 4, card * 8); // Rx Start count low byte 0
wcfxs_setreg(wc, card, 5, 0); // Rx Start count high byte 0
wcfxs_setreg(wc, card, 18, 0xff); // clear all interrupt
wcfxs_setreg(wc, card, 19, 0xff);
@@ -793,8 +773,6 @@ static int wcfxs_init_proslic(struct wcfxs *wc, int card)
wcfxs_setreg(wc, card, 1, 0x08);
#endif
- printk("Loopback: %02x\n", wcfxs_getreg(wc, card, 8));
-
#ifdef BOOST_RINGER
/* Beef up Ringing voltage to 89V */
if (wcfxs_setreg_indirect(wc, card, 23, 0x1d1))
@@ -815,40 +793,44 @@ static inline void wcfxs_check_hook(struct wcfxs *wc, int card)
hook = (res & 1);
if (hook != wc->lastrxhook[card]) {
/* Reset the debounce */
- wc->debounce[card] = 50;
+ wc->debounce[card] = 10;
#if 0
printk("Resetting debounce card %d hook %d, %d\n", card, hook, wc->debounce[card]);
#endif
} else {
- if (wc->debounce[card] > -1) {
+ if (wc->debounce[card] > 0) {
wc->debounce[card]--;
#if 0
printk("Sustaining hook %d, %d\n", hook, wc->debounce[card]);
#endif
- }
- }
- wc->lastrxhook[card] = hook;
- if (!wc->debounce[card]) {
+ if (!wc->debounce[card]) {
#if 0
- printk("Counted down debounce, newhook: %d...\n", hook);
+ printk("Counted down debounce, newhook: %d...\n", hook);
#endif
- wc->debouncehook[card] = hook;
+ wc->debouncehook[card] = hook;
+ }
+ if (!wc->oldrxhook[card] && wc->debouncehook[card]) {
+ /* Off hook */
+#if 1
+ if (debug)
+#endif
+ printk("wcfxs: Card %d Going off hook\n", card);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
+ wc->oldrxhook[card] = 1;
+
+ } else if (wc->oldrxhook[card] && !wc->debouncehook[card]) {
+ /* On hook */
+#if 1
+ if (debug)
+#endif
+ printk("wcfxs: Card %d Going on hook\n", card);
+ zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);
+ wc->oldrxhook[card] = 0;
+ }
+ }
}
+ wc->lastrxhook[card] = hook;
- if (!wc->oldrxhook[card] && wc->debouncehook[card]) {
- /* Off hook */
- if (debug)
- printk("wcfxs: Card %d Going off hook\n", card);
- zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK);
- wc->oldrxhook[card] = 1;
-
- } else if (wc->oldrxhook[card] && !wc->debouncehook[card]) {
- /* On hook */
- if (debug)
- printk("wcfxs: Card %d Going on hook\n", card);
- zt_hooksig(&wc->chans[card], ZT_RXSIG_ONHOOK);
- wc->oldrxhook[card] = 0;
- }
}
@@ -884,6 +866,8 @@ static int wcfxs_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long dat
static int wcfxs_open(struct zt_chan *chan)
{
struct wcfxs *wc = chan->pvt;
+ if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
+ return -ENODEV;
if (wc->dead)
return -ENODEV;
wc->usecount++;
@@ -945,7 +929,7 @@ static int wcfxs_initialize(struct wcfxs *wc)
int x;
/* Zapata stuff */
sprintf(wc->span.name, "WCFXS/%d", wc->pos);
- sprintf(wc->span.desc, "%s Board %d, %d modules\n", wc->variety, wc->pos + 1, wc->cards);
+ sprintf(wc->span.desc, "%s Board %d\n", wc->variety, wc->pos + 1);
wc->span.deflaw = ZT_LAW_MULAW;
for (x=0;x<wc->cards;x++) {
sprintf(wc->chans[x].name, "WCFXS/%d/%d", wc->pos, x);
@@ -999,11 +983,8 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
return -1;
}
/* Go to half-duty FSYNC */
- wcfxs_setcreg(wc, WC_SYNC, 0x1);
+ wcfxs_setcreg(wc, WC_SYNC, 0x00);
y = wcfxs_getcreg(wc, WC_SYNC);
- printk("SYNC is %d\n", y);
- /* Turn off LED's */
- wcfxs_setcreg(wc, WC_LEDS, 0xff);
} else {
printk("No freshmaker chip\n");
}
@@ -1051,11 +1032,16 @@ static int wcfxs_hardware_init(struct wcfxs *wc)
while(jiffies - oldjiffies < (HZ / 4) + 1);
for (x=0;x<wc->cards;x++) {
- if (wcfxs_init_proslic(wc, x)) {
- printk("Error initializing card %d\n", x);
- return -1;
- }
+ if (!wcfxs_init_proslic(wc, x)) {
+ printk("Module %d: Initialized\n", x);
+ wc->cardflag |= (1 << x);
+ } else
+ printk("Module %d: Not installed\n", x);
}
+ /* Return error if nothing initialized okay. */
+ if (!wc->cardflag)
+ return -1;
+ wcfxs_setcreg(wc, WC_SYNC, wc->cardflag << 1);
return 0;
}
@@ -1116,7 +1102,7 @@ static int __devinit wcfxs_init_one(struct pci_dev *pdev, const struct pci_devic
memset(wc, 0, sizeof(struct wcfxs));
spin_lock_init(&wc->lock);
wc->curcard = -1;
- wc->cards = 1;
+ wc->cards = 4;
wc->ioaddr = pci_resource_start(pdev, 0);
wc->dev = pdev;
wc->pos = x;