From c7560004aaa6726490d908eaaedcac62e3118701 Mon Sep 17 00:00:00 2001 From: markster Date: Fri, 9 Nov 2001 17:58:41 +0000 Subject: Version 0.1.2 from FTP git-svn-id: http://svn.digium.com/svn/zaptel/trunk@28 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- wct1xxp.c | 173 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 62 deletions(-) (limited to 'wct1xxp.c') diff --git a/wct1xxp.c b/wct1xxp.c index be821cf..a173941 100755 --- a/wct1xxp.c +++ b/wct1xxp.c @@ -57,6 +57,7 @@ #define WC_CURPOS 0x24 #define WC_SERC 0x2d +#define WC_FSCDELAY 0x2f #define WC_USERREG 0xc0 @@ -64,6 +65,9 @@ #define WC_LEDTEST 0x1 #define WC_VERSION 0x2 +/* Offset between transmit and receive */ +#define WC_OFFSET 4 + #define BIT_CS (1 << 5) #define BIT_OK (1 << 0) @@ -71,6 +75,16 @@ #define BIT_ERROR (1 << 2) #define BIT_ALARM (1 << 3) +static int chanmap[] = +{ 1,2,3, + 5,6,7, + 9,10,11, + 13,14,15, + 17,18,19, + 21,22,23, + 25,26,27, + 29,30,31 }; + struct t1xxp { struct pci_dev *dev; char *variety; @@ -84,8 +98,8 @@ struct t1xxp { unsigned long ioaddr; dma_addr_t readdma; dma_addr_t writedma; - volatile int *writechunk; /* Double-word aligned write memory */ - volatile int *readchunk; /* Double-word aligned read memory */ + volatile unsigned char *writechunk; /* Double-word aligned write memory */ + volatile unsigned char *readchunk; /* Double-word aligned read memory */ struct zt_span span; /* Span */ struct zt_chan chans[24]; /* Channels */ }; @@ -183,28 +197,74 @@ static int t1xxp_close(struct zt_chan *chan) static inline void handle_leds(struct t1xxp *wc) { if (wc->alarm) { +#ifdef FANCY_ALARM + if (wc->alarmtimer == wc->alarmthreshold << 1) { + wc->ledtestreg = wc->ledtestreg & ~BIT_ALARM; + control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); + } + if (wc->alarmtimer == 0x1f) { + wc->ledtestreg = wc->ledtestreg | BIT_ALARM; + control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); + wc->alarmtimer = -1; + wc->alarmthreshold = (wc->alarmthreshold + 1 & 0x1f); + } wc->alarmtimer++; - if (wc->alarmtimer == 40) { +#else + wc->alarmtimer++; + if (wc->alarmtimer == 160) { wc->ledtestreg = wc->ledtestreg | BIT_ALARM; control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); - } else if (wc->alarmtimer == 160) { + } else if (wc->alarmtimer == 480) { wc->ledtestreg = wc->ledtestreg & ~BIT_ALARM; control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); wc->alarmtimer = 0; } +#endif } -#if 0 - if (wc->alarmtimer == wc->alarmthreshold >> 2) { - wc->ledtestreg = wc->ledtestreg ^ BIT_ALARM; - control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); - } - if (wc->alarmtimer == 0xf) { - wc->ledtestreg = wc->ledtestreg ^ BIT_ALARM; - control_set_reg(wc, WC_LEDTEST, wc->ledtestreg); - wc->alarmtimer = -1; - wc->alarmthreshold = (wc->alarmthreshold + 1 & 0x1f); +} + +static void t1xxp_transmitprep(struct t1xxp *wc, int ints) +{ + volatile unsigned char *txbuf; + int x,y; + if (ints & 0x01) { + /* We just finished sending the first buffer, start filling it + now */ + txbuf = wc->writechunk; + } else { + /* Just finished sending second buffer, fill it now */ + txbuf = wc->writechunk + 32 * ZT_CHUNKSIZE; + } + for (y=0;yreadchunk; + } else { + rxbuf = wc->readchunk + ZT_CHUNKSIZE * 32; + } + for (x=0;x<24;x++) { + /* Must map received channels into appropriate data */ + tmpbuf[x] = rxbuf[(chanmap[x] + WC_OFFSET) & 0x1f]; + } + if (!(looper++ % 1000)) { + memcpy(tmpbuf, rxbuf, 32); + for (x=0;x<24;x++) + printk("%d: %d\n", x, (int)tmpbuf[x]); + } + } static void t1xxp_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -220,17 +280,13 @@ static void t1xxp_interrupt(int irq, void *dev_id, struct pt_regs *regs) printk("Got interrupt: 0x%04x\n", ints); gotint++; } - /* Initialize Write/Buffers to all blank data */ - memset((void *)wc->writechunk,0x55,ZT_MAX_CHUNKSIZE * 2 * 2 * 24 * 4); + if (ints & 0x0f) { + t1xxp_transmitprep(wc, ints); + t1xxp_receiveprep(wc, ints); + } handle_leds(wc); -#if 0 - if (ints & 0x0f) { - tjmodem_transmitprep(wc, ints); - tjmodem_receiveprep(wc, ints); - } -#endif if (ints & 0x10) printk("PCI Master abort\n"); @@ -264,8 +320,8 @@ static int t1xxp_reset(struct t1xxp *wc) static int t1xxp_hardware_init(struct t1xxp *wc) { int x; - /* Hardware Tigerjet stuff */ - /* Reset TJ chip and registers */ + /* Hardware PCI stuff */ + /* Reset chip and registers */ outb(DELAY | 0x0e, wc->ioaddr + WC_CNTL); /* Set all outputs to 0 */ outb(0x00, wc->ioaddr + WC_AUXD); @@ -276,7 +332,7 @@ static int t1xxp_hardware_init(struct t1xxp *wc) outb(0xc8, wc->ioaddr + WC_SERC); /* Internally delay FSC by one */ - outb(0x01, wc->ioaddr + 0x2f); + outb(0x01, wc->ioaddr + WC_FSCDELAY); /* Back to normal, with automatic DMA wrap around */ outb(DELAY | 0x01, wc->ioaddr + WC_CNTL); @@ -285,13 +341,18 @@ static int t1xxp_hardware_init(struct t1xxp *wc) outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, WC_CNTL); /* Setup DMA Addresses */ + /* Start at writedma */ outl(wc->writedma, wc->ioaddr + WC_DMAWS); /* Write start */ - outl(wc->writedma + ZT_CHUNKSIZE * 96, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */ - outl(wc->writedma + ZT_CHUNKSIZE * 192 - 4, wc->ioaddr + WC_DMAWE); /* End */ + /* First frame */ + outl(wc->writedma + ZT_CHUNKSIZE * 32, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */ + /* Second frame */ + outl(wc->writedma + ZT_CHUNKSIZE * 32 * 2 - 4, wc->ioaddr + WC_DMAWE); /* End */ outl(wc->readdma, wc->ioaddr + WC_DMARS); /* Read start */ - outl(wc->readdma + ZT_CHUNKSIZE * 96, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */ - outl(wc->readdma + ZT_CHUNKSIZE * 192 - 4, wc->ioaddr + WC_DMARE); /* End */ + /* First frame */ + outl(wc->readdma + ZT_CHUNKSIZE * 32, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */ + /* Second frame */ + outl(wc->readdma + ZT_CHUNKSIZE * 32 * 2 - 4, wc->ioaddr + WC_DMARE); /* End */ printk("Setting up DMA (write/read = %08lx/%08lx)\n", wc->writedma, wc->readdma); @@ -300,20 +361,10 @@ static int t1xxp_hardware_init(struct t1xxp *wc) /* Check out the controller */ printk("Controller version: %02x\n", control_get_reg(wc, WC_VERSION)); - control_set_reg(wc, WC_LEDTEST, 0xff); + control_set_reg(wc, WC_LEDTEST, 0x00); control_set_reg(wc, WC_CLOCK, 0x00); /* Pretend we're in alarm */ wc->alarm = 1; -#if 0 - printk("LED/Test Reg test: expected %02x, got %02x\n", 0x55, control_get_reg(wc, WC_LEDTEST)); - control_set_reg(wc, WC_LEDTEST, 0xAA); - printk("LED/Test Reg test: expected %02x, got %02x\n", 0xAA, control_get_reg(wc, WC_LEDTEST)); - - control_set_reg(wc, WC_CLOCK, 0x55); - printk("Clock Reg test: expected %02x, got %02x\n", 0x55, control_get_reg(wc, WC_CLOCK)); - control_set_reg(wc, WC_CLOCK, 0xAA); - printk("Clock Reg test: expected %02x, got %02x\n", 0xAA, control_get_reg(wc, WC_CLOCK)); -#endif return 0; #if 0 /* Reset all registers on the 2151 */ @@ -366,18 +417,6 @@ static void t1xxp_start_dma(struct t1xxp *wc) outb(DELAY | 0x01, wc->ioaddr + WC_CNTL); outb(0x01, wc->ioaddr + WC_OPER); printk("Started DMA\n"); - { int x; - for (x=0;x<10;x++) { - printk("%d) Read at %08lx\n", x, inl(wc->ioaddr + WC_CURPOS)); - udelay(10000); - } } - printk("0x0: %02x\n", (unsigned int)inb(wc->ioaddr + 0x0)); - printk("0x1: %02x\n", (unsigned int)inb(wc->ioaddr + 0x1)); - printk("0x2b: %02x\n", (unsigned int)inb(wc->ioaddr + 0x2b)); - printk("0x2c: %02x\n", (unsigned int)inb(wc->ioaddr + 0x2c)); - printk("0x2d: %02x\n", (unsigned int)inb(wc->ioaddr + 0x2d)); - printk("0x2e: %02x\n", (unsigned int)inb(wc->ioaddr + 0x2e)); - printk("0x2f: %02x\n", (unsigned int)inb(wc->ioaddr + 0x2f)); } static void t1xxp_stop_dma(struct t1xxp *wc) @@ -408,20 +447,21 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic wc->variety = (char *)(ent->driver_data); wc->writechunk = - (int *)pci_alloc_consistent(pdev, ZT_MAX_CHUNKSIZE * 2 * 2 * 24 * 4, &wc->writedma); + /* 32 channels, Double-buffer, Read/Write */ + (unsigned char *)pci_alloc_consistent(pdev, ZT_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma); if (!wc->writechunk) { printk("wcmodem: Unable to allocate DMA-able memory\n"); return -ENOMEM; } - /* Read is after the whole write piece (in double words) */ - wc->readchunk = wc->writechunk + ZT_CHUNKSIZE * 48; + /* Read is after the whole write piece (in bytes) */ + wc->readchunk = wc->writechunk + ZT_CHUNKSIZE * 32 * 2; - /* Same thing, but in bytes */ - wc->readdma = wc->writedma + ZT_CHUNKSIZE * 192; + /* Same thing... */ + wc->readdma = wc->writedma + ZT_CHUNKSIZE * 32 * 2; /* Initialize Write/Buffers to all blank data */ - memset((void *)wc->writechunk,0xff,ZT_MAX_CHUNKSIZE * 2 * 2 * 24 * 4); + memset((void *)wc->writechunk,0x00,ZT_MAX_CHUNKSIZE * 2 * 2 * 32); /* Enable bus mastering */ pci_set_master(pdev); @@ -440,8 +480,6 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic /* Enable interrupts */ t1xxp_enable_interrupts(wc); - /* Initialize Write/Buffers to all blank data */ - memset((void *)wc->writechunk,0,ZT_MAX_CHUNKSIZE * 2 * 2 * 24 * 4); /* Start DMA */ t1xxp_start_dma(wc); @@ -453,6 +491,15 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic return res; } +static void t1xxp_stop_stuff(struct t1xxp *wc) +{ + /* Kill clock */ + control_set_reg(wc, WC_CLOCK, 0); + + /* Turn off LED's */ + control_set_reg(wc, WC_LEDTEST, 0); +} + static void __devexit t1xxp_remove_one(struct pci_dev *pdev) { struct t1xxp *wc = pci_get_drvdata(pdev); @@ -464,11 +511,13 @@ static void __devexit t1xxp_remove_one(struct pci_dev *pdev) /* In case hardware is still there */ t1xxp_disable_interrupts(wc); + t1xxp_stop_stuff(wc); + /* Immediately free resources */ pci_free_consistent(pdev, ZT_MAX_CHUNKSIZE * 2 * 2 * 24 * 4, (void *)wc->writechunk, wc->writedma); free_irq(pdev->irq, wc); - /* Reset TJ chip and registers */ + /* Reset PCI chip and registers */ outb(DELAY | 0x0e, wc->ioaddr + WC_CNTL); /* Release span, possibly delayed */ -- cgit v1.2.3