diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-10-04 20:46:11 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-10-04 20:46:11 +0000 |
commit | 4a37f022ab8af3d8a9412b85e220956bcf0d7ccb (patch) | |
tree | 010609731bfabfbd50ebddd929acd7452cf6093f | |
parent | 47bb8692285b72530c8bfdfe0ce777aa8b594592 (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-x | tor2.c | 83 | ||||
-rwxr-xr-x | wcfxs.c | 164 | ||||
-rwxr-xr-x | wctdm.c | 164 |
3 files changed, 207 insertions, 204 deletions
@@ -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: @@ -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; @@ -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; |