summaryrefslogtreecommitdiff
path: root/wct1xxp.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-11-09 17:58:41 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-11-09 17:58:41 +0000
commitc7560004aaa6726490d908eaaedcac62e3118701 (patch)
tree7a075db2dab71fbe7b4f3d62e98ade20d771e23b /wct1xxp.c
parent38bed60f5d8d4c0d75854538a9f905bfd33ec54f (diff)
Version 0.1.2 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@28 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct1xxp.c')
-rwxr-xr-xwct1xxp.c173
1 files changed, 111 insertions, 62 deletions
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;y<ZT_CHUNKSIZE;y++) {
+ for (x=0;x<24;x++) {
+ /* Put channel number as outgoing data */
+ txbuf[y * 32 + chanmap[x]] = (unsigned char)x;
}
-#endif
+ }
+}
+
+static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
+{
+ volatile unsigned char *rxbuf;
+ static int looper=0;
+ int x;
+ unsigned char tmpbuf[32];
+ if (ints & 0x08) {
+ /* Just received first buffer */
+ rxbuf = wc->readchunk;
+ } 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 */