[Pkg-voip-commits] r5757 - in /zaptel/trunk: debian/changelog kernel/cwain/cwain.c kernel/cwain/cwain.h kernel/ztgsm/ztgsm.c kernel/ztgsm/ztgsm.h

paravoid at alioth.debian.org paravoid at alioth.debian.org
Wed May 21 00:57:12 UTC 2008


Author: paravoid
Date: Wed May 21 00:57:12 2008
New Revision: 5757

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=5757
Log:
* Update qozap from bristuff-0.4.0-RC1.
* Update cwain from bristuff-0.4.0-RC1.
* Update ztgsm from bristuff-0.4.0-RC1.
  - reduced baudrate (serial interface to gsm modules) to be more robust
    against irq misses in loaded systems
  - improved serial debug output
  - added module parameter "baudrate" (the default is 19200)
  - added AT commands for SIM card selection
  - added AT commands for shutting down/starting GSM modules

Modified:
    zaptel/trunk/debian/changelog
    zaptel/trunk/kernel/cwain/cwain.c
    zaptel/trunk/kernel/cwain/cwain.h
    zaptel/trunk/kernel/ztgsm/ztgsm.c
    zaptel/trunk/kernel/ztgsm/ztgsm.h

Modified: zaptel/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/zaptel/trunk/debian/changelog?rev=5757&op=diff
==============================================================================
--- zaptel/trunk/debian/changelog (original)
+++ zaptel/trunk/debian/changelog Wed May 21 00:57:12 2008
@@ -1,10 +1,18 @@
 zaptel (1:1.4.10.1~dfsg-2) UNRELEASED; urgency=low
 
-  * Update qozap from bristuff-0.4.0-RC1
+  * Update qozap from bristuff-0.4.0-RC1.
     - fixed duoBRI miniPCI detection in qozap.
     - added support for PCIe variants of duoBRI and quadBRI.
-
- -- Faidon Liambotis <paravoid at debian.org>  Wed, 21 May 2008 03:46:52 +0300
+  * Update cwain from bristuff-0.4.0-RC1.
+  * Update ztgsm from bristuff-0.4.0-RC1.
+    - reduced baudrate (serial interface to gsm modules) to be more robust
+      against irq misses in loaded systems
+    - improved serial debug output
+    - added module parameter "baudrate" (the default is 19200)
+    - added AT commands for SIM card selection
+    - added AT commands for shutting down/starting GSM modules
+
+ -- Faidon Liambotis <paravoid at debian.org>  Wed, 21 May 2008 03:53:30 +0300
 
 zaptel (1:1.4.10.1~dfsg-1) unstable; urgency=low
 

Modified: zaptel/trunk/kernel/cwain/cwain.c
URL: http://svn.debian.org/wsvn/pkg-voip/zaptel/trunk/kernel/cwain/cwain.c?rev=5757&op=diff
==============================================================================
--- zaptel/trunk/kernel/cwain/cwain.c (original)
+++ zaptel/trunk/kernel/cwain/cwain.c Wed May 21 00:57:12 2008
@@ -153,7 +153,7 @@
     if (!(cwaintmp->span.flags & ZT_FLAG_RUNNING)) {
 	return;
     }
-    if ((cwaintmp->type == 0xb553) || (cwaintmp->type == 0xb554)) {
+    if ((cwaintmp->type == 0xb553) || (cwaintmp->type == 0xb554) || (cwaintmp->type == 0xb555)) {
 	/* sync status */
 	if (((cwaintmp->sync_sta & 0x07) == 0x07) && cwaintmp->sync) {
 	    cwaintmp->leds[0] = 1;    
@@ -231,8 +231,14 @@
     cwain_outb(cwaintmp,cwain_R_CTRL,0x0); 
 
     /* no blinky blink */
-    cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10);
-    cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
+    if (cwaintmp->type == 0xb555) {
+	cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10 | 0x02);
+	cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
+	cwain_outb(cwaintmp,cwain_R_GPIO_EN0,0x08 | 0x04);
+    } else {
+	cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10);
+	cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
+    }
     cwain_outb(cwaintmp,cwain_R_GPIO_OUT1,0x0f);
 
     /* IRQs off */
@@ -325,13 +331,14 @@
 	
 	    spin_lock_init(&cwaintmp->lock);
 	    cwaintmp->pcibus = cwainspan->pcibus;
-	    cwaintmp->spans = cwainspan->type - 46419;
+//	    cwaintmp->spans = cwainspan->type - 46419;
+	    cwaintmp->spans = (cwainspan->type & (2321 * 20)) - 46419;
 	    cwaintmp->span[0] = cwainspan;
 	    cwaintmp->cardID = cwainspan->cardID;
 	    cwaintmp->syncs[0] = -1;
 	    cwain_register_card(cwaintmp);
 	} else {
-	    cwaintmp->spans = cwainspan->type - 46418;
+	    cwaintmp->spans = (cwainspan->type & (2321 * 20)) - 46418;
 	    if (cwainspan->cardID < cwaintmp->cardID) {
 		cwaintmp->cardID = cwainspan->cardID;
 		cwaintmp->span[1] = cwaintmp->span[0];
@@ -342,8 +349,8 @@
 		cwaintmp->syncs[1] = -1;
 	    }
 	    printk(KERN_INFO
-	        "cwain: Junghanns.NET doubleE1 PCI ISDN card configured at mem (%lx / %lx) IRQ %d HZ %d CardID (%d / %d) bus %#x\n",
-	          (unsigned long) cwaintmp->span[0]->pci_io, (unsigned long) cwaintmp->span[1]->pci_io,
+	        "cwain: Junghanns.NET doubleE1 PCI ISDN %d.0 card configured at mem (%lx / %lx) IRQ %d HZ %d CardID (%d / %d) bus %#x\n",
+	        (cwainspan->type - 0xb553),  (unsigned long) cwaintmp->span[0]->pci_io, (unsigned long) cwaintmp->span[1]->pci_io,
 	        cwaintmp->span[0]->irq, HZ, cwaintmp->span[0]->cardID, cwaintmp->span[1]->cardID, cwaintmp->pcibus);
 	}
     }
@@ -1106,6 +1113,16 @@
 
 static inline void cwain_audio_run(struct zt_cwain *cwaintmp) {
     int fifo=0;
+    
+    if (cwaintmp->wdp) {
+	if (cwaintmp->wdp == 0x04) {
+	    cwaintmp->wdp = 0x08;
+	} else {
+	    cwaintmp->wdp = 0x04;
+	}
+	cwain_outb(cwaintmp, cwain_R_GPIO_OUT0, cwaintmp->wdp);
+    }
+    
     if (hdlcnet) return;
     
     if (hw_hdlc) {
@@ -1227,19 +1244,25 @@
 	if (sync_ok) {
 	    switch (cwainspan->type) {
 		case 0xb553:
-		    sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) SYNCED",cwainspan->cardno,cwainspan->cardID);
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET singleE1 PCI ISDN %d (cardID %d) SYNCED",cwainspan->cardno,cwainspan->cardID);
 	    	    break;
     		case 0xb554:
-		    sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) SYNCED",cwainspan->cardno,cwainspan->cardID);
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET doubleE1 PCI ISDN %d (cardID %d) (1 E1 port) SYNCED",cwainspan->cardno,cwainspan->cardID);
+		    break;
+    		case 0xb555:
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET doubleE1 PCI ISDN 2.0 %d (cardID %d) (1 E1 port) SYNCED",cwainspan->cardno,cwainspan->cardID);
 		    break;
 	    }
 	} else {
 	    switch (cwainspan->type) {
 		case 0xb553:
-		    sprintf(cwainspan->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET singleE1 PCI ISDN %d (cardID %d) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
 		    break;
     		case 0xb554:
-		    sprintf(cwainspan->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET doubleE1 PCI ISDN %d (cardID %d) (1 E1 port) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
+	    	    break;
+    		case 0xb555:
+		    snprintf(cwainspan->span.desc, sizeof(cwainspan->span.desc), "Junghanns.NET doubleE1 PCI ISDN 2.0 %d (cardID %d) (1 E1 port) NO SYNC (sync_sta = %#x)",cwainspan->cardno,cwainspan->cardID, sync_sta);
 	    	    break;
 	    }
 	}
@@ -1813,6 +1836,9 @@
     cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
     cwain_inb(cwaintmp,cwain_R_STATUS);
 
+    cwain_outb(cwaintmp,cwain_R_GPIO_EN0,0x00);
+    cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x00);
+
 
     span->flags &= ~ZT_FLAG_RUNNING;
 
@@ -1857,10 +1883,14 @@
 	sprintf(cwaintmp->span.name,"cwain/%d",cwaintmp->cardno);
 	switch (cwaintmp->type) {
 	    case 0xb553:
-		sprintf(cwaintmp->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d)",cwaintmp->cardno,cwaintmp->cardID);
+		snprintf(cwaintmp->span.desc, sizeof(cwaintmp->span.desc), "Junghanns.NET singleE1 PCI ISDN %d (cardID %d)",cwaintmp->cardno,cwaintmp->cardID);
 		break;
 	    case 0xb554:
-		sprintf(cwaintmp->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
+		snprintf(cwaintmp->span.desc, sizeof(cwaintmp->span.desc), "Junghanns.NET doubleE1 PCI ISDN %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
+		break;
+	    case 0xb555:
+		snprintf(cwaintmp->span.desc, sizeof(cwaintmp->span.desc), "Junghanns.NET doubleE1 PCI ISDN 2.0 %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
+		cwaintmp->wdp = 0x04;
 		break;
 	    default:
 		return -1;
@@ -2038,7 +2068,7 @@
 	/* disable interrupts */
 	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
 
-        if (((tmp->subsystem_device==0xb553) || (tmp->subsystem_device==0xb554))&& (pcidid == PCI_DEVICE_ID_CCD_E)) {
+        if (((tmp->subsystem_device==0xb553)|| (tmp->subsystem_device==0xb554) || (tmp->subsystem_device==0xb555))&& (pcidid == PCI_DEVICE_ID_CCD_E)) {
 	    dips = (cwain_inb(cwaintmp,cwain_R_GPI_IN0) >> 5);
 	    cid = 7;
 	    for (i=0;i<3;i++) {

Modified: zaptel/trunk/kernel/cwain/cwain.h
URL: http://svn.debian.org/wsvn/pkg-voip/zaptel/trunk/kernel/cwain/cwain.h?rev=5757&op=diff
==============================================================================
--- zaptel/trunk/kernel/cwain/cwain.h (original)
+++ zaptel/trunk/kernel/cwain/cwain.h Wed May 21 00:57:12 2008
@@ -33,6 +33,7 @@
     
     /* blinky blink */
     unsigned char leds[4];
+    unsigned int wdp;
 
     /* B chan buffers */
     unsigned char rxbuf[31][ZT_CHUNKSIZE];

Modified: zaptel/trunk/kernel/ztgsm/ztgsm.c
URL: http://svn.debian.org/wsvn/pkg-voip/zaptel/trunk/kernel/ztgsm/ztgsm.c?rev=5757&op=diff
==============================================================================
--- zaptel/trunk/kernel/ztgsm/ztgsm.c (original)
+++ zaptel/trunk/kernel/ztgsm/ztgsm.c Wed May 21 00:57:12 2008
@@ -31,6 +31,7 @@
 static int ztgsm_spans = 0;
 static struct pci_dev *multi_gsm = NULL;
 static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
+static long baudrate=19200;
 
 void ztgsm_init_xbar(struct ztgsm_card *gsmtmp) {
     int i = 0;
@@ -45,7 +46,7 @@
     printk(KERN_INFO "ztgsm: Powering up span %d ...", span);
     spin_lock_irqsave(&(gsmtmp->lock),flags);
 	gsmtmp->gsmspan[span].led = 0xC1;
-	gsmtmp->dtr_on_off &= ~ (1 << span);
+	gsmtmp->dtr_on_off &= ~ (1 << span); 	/* on_off_n low */
 	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
     spin_unlock_irqrestore(&(gsmtmp->lock),flags);
 
@@ -53,7 +54,7 @@
     schedule_timeout((1000 * HZ) / 1000);
 
     spin_lock_irqsave(&(gsmtmp->lock),flags);
-        gsmtmp->dtr_on_off |= 1 << span;
+        gsmtmp->dtr_on_off |= 1 << span;	/* on_off_n high */
 	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
 
 	gsmtmp->power[span] = 1;
@@ -72,9 +73,9 @@
 
     spin_lock_irqsave(&(gsmtmp->lock),flags);
 	gsmtmp->gsmspan[span].led = 0xC0;
+    
+	gsmtmp->dtr_on_off &= ~ (1 << span);	/* on_off_n low */
 	printk(KERN_INFO "ztgsm: Powering down span %d (SER_DTR_ON_OFF %x)...", span, gsmtmp->dtr_on_off);
-    
-	gsmtmp->dtr_on_off &= ~ (1 << span);
 	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
     spin_unlock_irqrestore(&(gsmtmp->lock),flags);
 
@@ -82,7 +83,7 @@
     schedule_timeout((2500 * HZ) / 1000);
 
     spin_lock_irqsave(&(gsmtmp->lock),flags);
-        gsmtmp->dtr_on_off |= (1 << span);
+        gsmtmp->dtr_on_off |= (1 << span);	/* on_off_n high */
 	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
 	gsmtmp->power[span] = 0;
 	gsmtmp->gsmspan[span].led = 0x80;
@@ -100,15 +101,15 @@
 	gsmtmp->gsmspan[2].led = 0xC1;
         gsmtmp->gsmspan[3].led = 0xC1;
 
-	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xf0);
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xf0);	/* set ON_OFF_N to low for 1000 ms */
     spin_unlock_irqrestore(&(gsmtmp->lock),flags);
 
     set_current_state(TASK_UNINTERRUPTIBLE);
     schedule_timeout((1000 * HZ) / 1000);
 
     spin_lock_irqsave(&(gsmtmp->lock),flags);
-	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xff);
-	ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0x0); /* 1 == -12 v */
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0f);	/* set ON_OFF_N to high, DTR to low */
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0x0); 		
 
 	gsmtmp->power[0] = 1;
 	gsmtmp->power[1] = 1;
@@ -137,14 +138,15 @@
 	gsmtmp->gsmspan[2].led = 0xC0;
         gsmtmp->gsmspan[3].led = 0xC0;
 	
-	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0);
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xf0);
     spin_unlock_irqrestore(&(gsmtmp->lock),flags);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((2500 * HZ) / 1000);
 
     spin_lock_irqsave(&(gsmtmp->lock),flags);
-	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0x0f);
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, 0xff);
+	ztgsm_outdw_io(gsmtmp, ztgsm_SER_RTS_O, 0xF); 
 
 	gsmtmp->power[0] = 0;
 	gsmtmp->power[1] = 0;
@@ -255,10 +257,30 @@
 
 void ztgsm_resetCard(struct ztgsm_card *gsmtmp) {
     unsigned long flags;
+    int i;
     spin_lock_irqsave(&(gsmtmp->lock),flags);
 //    pci_write_config_word(gsmtmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
     
-    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x12);
+    switch (baudrate) {
+	case 9600:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0xD5);
+	    break;
+	case 19200:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x6B);
+	    break;
+	case 38400:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x35);
+	    break;
+	case 57600:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x24);
+	    break;
+	case 115200:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x12);
+	    break;
+	default:
+	    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_DIV, 0x6B);	/* 19200 */
+    }
+
     ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_PRE_DIV, 0x06);
 //    ztgsm_outdw_io(gsmtmp, ztgsm_SER_CLK_PRE_DIV, 0x03);
 //    ztgsm_outdw_io(gsmtmp, ztgsm_PCM_CLK_PRE_DIV, 0x06);
@@ -272,6 +294,9 @@
 
     gsmtmp->ticks = 0;
     gsmtmp->clicks = 0;
+    
+    for (i=0; i<4; i++)
+	gsmtmp->ton_off_toggle[i] = -1;
 
     spin_unlock_irqrestore(&(gsmtmp->lock),flags);
 }
@@ -281,11 +306,13 @@
     spin_lock_irqsave(&(gsmtmp->lock),flags);
     ztgsm_outdw_io(gsmtmp, ztgsm_PCM_FC_TOG_BIT, 0x03);
     ztgsm_outdw_io(gsmtmp, ztgsm_SER_INT_MASK, 0x1FFFF);
-    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RX_WATERMARK, 0x0A);
+    ztgsm_outdw_io(gsmtmp, ztgsm_SER_RX_WATERMARK, 0x0);
     if (sim) {
-	ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, sim);
+	gsmtmp->sim_sel = sim;
+	ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, gsmtmp->sim_sel);
     } else {
-	ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, 0x0);
+	gsmtmp->sim_sel = 0;
+	ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, gsmtmp->sim_sel);
     }
     ztgsm_outdw_io(gsmtmp, ztgsm_PCM_SAP_EN, 0x0);
     ztgsm_outdw_io(gsmtmp, ztgsm_PCM_MASK_LAST, 0x001F0000 | 0x1F); /* PCM32 0x100 frames */
@@ -403,14 +430,22 @@
 //	if (debug) 
 //	    printk(KERN_CRIT "ztgsm: SER_RX_COUNT_%d [wr_ptr %d rd_ptr %d count %d]\n", span, wr_ptr, rd_ptr, rx_count);
 	if ((gsmtmp->ser_rx_idx[span] + rx_count) < ztgsm_SER_BUF_SIZE) {
-	    if (debug) printk(KERN_CRIT "ztgsm: SER_RX span %d [", span);
+	    if (debug) printk(KERN_INFO "ztgsm: span %d SER_RX [ ", span);
 	    for (i=0;i<rx_count; i++) {
 		data = ztgsm_indw_io(gsmtmp, rxdreg);
-		if (debug) printk(" %#x", data);
+		if (debug) {
+		    if (data == 0xd) {
+			printk("\\r");
+		    } else if (data == 0xa) {
+			printk("\\n");
+		    } else {
+			printk("%c", data);
+		    }
+		}
 		if (gsmtmp->gsmspan[span].span.flags & ZT_FLAG_RUNNING)
 		    gsmtmp->ser_rx_buf[span][gsmtmp->ser_rx_idx[span]++] = data;
 	    }
-    	    if (debug) printk("]\n");
+    	    if (debug) printk(" ]\n");
 	} else {
 	    printk(KERN_INFO "ztgsm: RX buffer overflow on span %d\n", span);
 	}
@@ -423,13 +458,18 @@
         
     if (gsmtmp->ser_rx_idx[span]) {
 	memcpy(gsmtmp->drxbuf[span], &gsmtmp->ser_rx_buf[span], gsmtmp->ser_rx_idx[span]);
-	if (debug) {
-	    printk(KERN_INFO "ztgsm: span %d RX [ \n", span);
+	if (debug > 1) {
+	    printk(KERN_INFO "ztgsm: span %d RX [ ", span);
 	    for (i=0;i<gsmtmp->ser_rx_idx[span]; i++) {
-		if (gsmtmp->ser_rx_buf[span][i] != 0x0d)
+		if (gsmtmp->ser_rx_buf[span][i] == 0xd) {
+		    printk("\\r");
+		} else if (gsmtmp->ser_rx_buf[span][i] == 0xa) {
+		    printk("\\n");
+		} else {
 		    printk("%c", gsmtmp->ser_rx_buf[span][i]);
-	    }
-    	    printk("]\n");
+		}
+	    }
+    	    printk(" ]\n");
 	}
 	gsmtmp->gsmspan[span].chans[1].eofrx = 1;
 	gsmtmp->gsmspan[span].chans[1].bytes2receive = gsmtmp->ser_rx_idx[span];
@@ -481,12 +521,12 @@
 	    if (debug)
 		printk(KERN_INFO "ztgsm: span %d SER_TX [ ", span);
 	    for (i=0;i<count; i++) {
-		if (debug)
+		if (debug && (gsmtmp->ser_tx_buf[span][i] > 0x10))
 	    	    printk("%c", gsmtmp->ser_tx_buf[span][i]);
 		ztgsm_outdw_io(gsmtmp, txdreg, gsmtmp->ser_tx_buf[span][i]);
 	    }
 	    if (debug)
-	        printk("]\n");
+	        printk(" ]\n");
 	    gsmtmp->ser_tx_idx[span] -= count;
 	    if (gsmtmp->ser_tx_idx[span] > 0) {
 		memmove(&gsmtmp->ser_tx_buf[span][0], &gsmtmp->ser_tx_buf[span][i], gsmtmp->ser_tx_idx[span]);
@@ -506,24 +546,68 @@
 static int ztgsm_zap_tx(struct ztgsm_card *gsmtmp, int span) {
     struct ztgsm_span *gsmspan = NULL;
     int i = 0;
-
+    int poweroff_cmd = 0;
+    int poweron_cmd = 0;
     gsmspan = &gsmtmp->gsmspan[span];
     if (!gsmspan)
 	 return -1;
 	if (gsmspan->chans[1].bytes2transmit) {
-	    if (debug) {
+	    if (debug > 1) {
 		printk(KERN_INFO "ztgsm: span %d TX [ ", span);
 		for (i=0;i<gsmspan->chans[1].bytes2transmit; i++) {
-		    printk("%c ", gsmtmp->dtxbuf[span][i]);
+		    if (gsmtmp->dtxbuf[span][i] > 0x10)
+			printk("%c", gsmtmp->dtxbuf[span][i]);
 		}
-	        printk("]\n");
-	    }
-	    if (gsmtmp->ser_tx_idx[span] + gsmspan->chans[1].bytes2transmit < ztgsm_SER_BUF_SIZE) {
-		memcpy(&gsmtmp->ser_tx_buf[span][gsmtmp->ser_tx_idx[span]], gsmtmp->dtxbuf[span], gsmspan->chans[1].bytes2transmit);
-		gsmtmp->ser_tx_idx[span] += gsmspan->chans[1].bytes2transmit;
-		ztgsm_ser_tx(gsmtmp, span);
-	    } else {
-		printk(KERN_INFO "ztgsm: TX buffer overflow on span %d (TX_IDX %d BTT %d)\n", span, gsmtmp->ser_tx_idx[span] , gsmspan->chans[1].bytes2transmit);
+	        printk(" ]\n");
+	    }
+	    if ((gsmtmp->dtxbuf[span][0] == 'A') && (gsmtmp->dtxbuf[span][1] == 'T') && (gsmtmp->dtxbuf[span][2] == '+') && (gsmtmp->dtxbuf[span][3] == 'P') && (gsmtmp->dtxbuf[span][4] == 'O') && (gsmtmp->dtxbuf[span][5] == 'W') && (gsmtmp->dtxbuf[span][6] == 'E') && (gsmtmp->dtxbuf[span][7] == 'R') && (gsmtmp->dtxbuf[span][8] == '=') && (gsmtmp->dtxbuf[span][9] == '1') && (gsmtmp->dtxbuf[span][10] == '\r')) {
+		if (debug) printk(KERN_INFO "ztgsm: span %d received power on AT command\n", span);
+		gsmtmp->dtr_on_off &= ~(1 << span); 	/* on_off_n low */
+		ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
+		gsmtmp->ton_off_toggle[span] = 700;
+		gsmtmp->gsmspan[span].led = 0xC1;
+		gsmtmp->power[span] = 1;
+		poweron_cmd = 1;
+	    } else if ((gsmtmp->dtxbuf[span][0] == 'A') && (gsmtmp->dtxbuf[span][1] == 'T') && (gsmtmp->dtxbuf[span][2] == '+') && (gsmtmp->dtxbuf[span][3] == 'M') && (gsmtmp->dtxbuf[span][4] == 'R') && (gsmtmp->dtxbuf[span][5] == 'S') && (gsmtmp->dtxbuf[span][6] == 'T') && (gsmtmp->dtxbuf[span][7] == '\r')) {
+		if (debug) printk(KERN_INFO "ztgsm: span %d received power off AT command\n", span);
+		gsmtmp->gsmspan[span].led = 0x80;
+		gsmtmp->power[span] = 0;
+		poweroff_cmd = 1;
+	    } else if ((gsmtmp->dtxbuf[span][0] == 'a') && (gsmtmp->dtxbuf[span][1] == 't') && (gsmtmp->dtxbuf[span][2] == '+') && (gsmtmp->dtxbuf[span][3] == 'm') && (gsmtmp->dtxbuf[span][4] == 'r') && (gsmtmp->dtxbuf[span][5] == 's') && (gsmtmp->dtxbuf[span][6] == 't') && (gsmtmp->dtxbuf[span][7] == '\r')) {
+		if (debug) printk(KERN_INFO "ztgsm: span %d received power off AT command\n", span);
+		gsmtmp->gsmspan[span].led = 0x80;
+		gsmtmp->power[span] = 0;
+		poweroff_cmd = 1;
+	    } else if ((gsmtmp->dtxbuf[span][0] == 'A') && (gsmtmp->dtxbuf[span][1] == 'T') && (gsmtmp->dtxbuf[span][2] == '+') && (gsmtmp->dtxbuf[span][3] == 'P') && (gsmtmp->dtxbuf[span][4] == 'O') && (gsmtmp->dtxbuf[span][5] == 'W') && (gsmtmp->dtxbuf[span][6] == 'E') && (gsmtmp->dtxbuf[span][7] == 'R') && (gsmtmp->dtxbuf[span][8] == '=') && (gsmtmp->dtxbuf[span][9] == '0') && (gsmtmp->dtxbuf[span][10] == '\r')) {
+		if (debug) printk(KERN_INFO "ztgsm: span %d received power off AT command\n", span);
+		gsmtmp->dtr_on_off &= ~(1 << span); 	/* on_off_n low */
+		ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
+		gsmtmp->gsmspan[span].led = 0xC0;
+		gsmtmp->ton_off_toggle[span] = 2200;
+		gsmtmp->power[span] = 0;
+	    } else if ((gsmtmp->dtxbuf[span][0] == 'A') && (gsmtmp->dtxbuf[span][1] == 'T') && (gsmtmp->dtxbuf[span][2] == '+') && (gsmtmp->dtxbuf[span][3] == 'S') && (gsmtmp->dtxbuf[span][4] == 'I') && (gsmtmp->dtxbuf[span][5] == 'M') && (gsmtmp->dtxbuf[span][6] == '=') && (gsmtmp->dtxbuf[span][8] == '\r')) {
+		if (debug) printk(KERN_INFO "ztgsm: span %d received SIM select AT command, sim = %c\n", span, gsmtmp->dtxbuf[span][7]);
+		if (gsmtmp->dtxbuf[span][7] == '0') {
+		    gsmtmp->sim_sel &= ~(1 << span);
+		    ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, gsmtmp->sim_sel);
+		    if (debug) printk(KERN_INFO "ztgsm: span %d now using onboard SIM card reader. Setting sim_sel to %d.\n", span, gsmtmp->sim_sel);
+		} else if (gsmtmp->dtxbuf[span][7] == '1') {
+		    gsmtmp->sim_sel |= (1 << span);
+		    ztgsm_outdw_io(gsmtmp, ztgsm_SIM_SEL, gsmtmp->sim_sel);
+		    if (debug) printk(KERN_INFO "ztgsm: span %d now using external SIM card reader. Setting sim_sel to %d.\n", span, gsmtmp->sim_sel);
+		} else {
+		    printk(KERN_INFO "ztgsm: span %d received invalied SIM select AT command, sim = %c\n", span,  gsmtmp->dtxbuf[span][7]);
+		}
+		poweron_cmd = 1;
+	    }
+	    if ((gsmtmp->power[span] || poweroff_cmd) && (!poweron_cmd)) {
+		if (gsmtmp->ser_tx_idx[span] + gsmspan->chans[1].bytes2transmit < ztgsm_SER_BUF_SIZE) {
+		    memcpy(&gsmtmp->ser_tx_buf[span][gsmtmp->ser_tx_idx[span]], gsmtmp->dtxbuf[span], gsmspan->chans[1].bytes2transmit);
+		    gsmtmp->ser_tx_idx[span] += gsmspan->chans[1].bytes2transmit;
+		    ztgsm_ser_tx(gsmtmp, span);
+		} else {
+		    printk(KERN_INFO "ztgsm: TX buffer overflow on span %d (TX_IDX %d BTT %d)\n", span, gsmtmp->ser_tx_idx[span] , gsmspan->chans[1].bytes2transmit);
+		}
 	    }
 	}
 		
@@ -702,7 +786,7 @@
 	    if (gsmspan->span.flags & ZT_FLAG_RUNNING) {
 		/* oh zaptel! tell us what to transmit... */
     		zt_transmit(&gsmspan->span);
-		if (debug && (gsmspan->chans[1].bytes2transmit > 0))
+		if ((debug > 1) && (gsmspan->chans[1].bytes2transmit > 0))
 		    printk(KERN_CRIT "ztgsm: span %d bytes2transmit = %d\n", s, gsmspan->chans[1].bytes2transmit);
 		ztgsm_span_tx(gsmtmp, s);
 		ztgsm_zap_tx(gsmtmp, s);
@@ -726,6 +810,7 @@
     unsigned char mods = 0;
     int s = 0;
     int rx_count = 0;
+    int dtr_on_off = 0;
     unsigned long flags;
     signed int jitter = 0;
     
@@ -766,50 +851,79 @@
 		if ((debug > 1) && gsmtmp->jitter_offset)
 		    printk(KERN_INFO "ztgsm: lagged IRQ, framecnt %d last_framecnt %d (offset %d)\n", gsmtmp->framecnt, gsmtmp->last_framecnt, gsmtmp->jitter_offset);
 	    }
+
 	    if (gsmtmp->jitter_offset >= 0) {
 		ztgsm_run(gsmtmp);
 	    }
-
-    	    for (s=0; s<gsmtmp->gsmspans; s++) {
-	        rx_count = ztgsm_ser_rx(gsmtmp, s);
-	    }
+	    if (!(gsmtmp->ticks % 100)) {
+		for (s=0; s < gsmtmp->gsmspans; s++) {
+		    if (gsmtmp->ton_off_toggle[s] >= 0) {
+			gsmtmp->ton_off_toggle[s] -= 100;
+			if (gsmtmp->ton_off_toggle[s] <= 0) {
+			    /* timer expired */ 
+			    gsmtmp->ton_off_toggle[s] = -1;
+			    dtr_on_off = gsmtmp->dtr_on_off & (1 << s);
+			    if (dtr_on_off) {
+				if (debug)
+				    printk(KERN_INFO "ztgsm: setting on_off to low for span %d\n",s);
+				gsmtmp->dtr_on_off &= ~(1 << s); 	/* on_off_n low */
+				ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
+			    } else {
+				if (debug)
+				    printk(KERN_INFO "ztgsm: setting on_off to high for span %d\n",s);
+    				gsmtmp->dtr_on_off |= 1 << s;		/* on_off_n high */
+				ztgsm_outdw_io(gsmtmp, ztgsm_SER_DTR_ON_OFF, gsmtmp->dtr_on_off);
+			    }
+			    if (gsmtmp->power[s]) {
+				gsmtmp->gsmspan[s].led = 0x81;
+			    } else {
+				gsmtmp->gsmspan[s].led = 0x80;
+			    }
+			}
+		    }
+		}
+	    }
+
 	    if (!(gsmtmp->ticks % 300))
 	        ztgsm_leds(gsmtmp, gsmtmp->ticks);
+
 	    if (!(gsmtmp->ticks % 1000)) {
 		if (debug > 2)
 		    printk(KERN_INFO "ztgsm: TICK\n");
 	        gsmtmp->ticks = 0;
     	    }
-	} else if (ser_status & 0x0F) {
+	}
+	if (ser_status & 0x0F) {
 	    mods = (ser_status & 0x0F);
 	    for (s=0; s<gsmtmp->gsmspans; s++) {
 		if (mods & (1 << s)) {
 		    rx_count = ztgsm_ser_rx(gsmtmp, s);
-		    if (debug) 
+//		    if (debug) 
 			printk(KERN_INFO "ztgsm: TX fifo overrun on span %d\n", s);
 		}
 	    }
-	} else if (ser_status & 0xF0) {
+	}
+	if (ser_status & 0xF0) {
 	    mods = (ser_status & 0xF0) >> 4;
-		    if (debug) 
-			printk(KERN_INFO "ztgsm: RX mods %d\n", mods);
 	    for (s=0; s<gsmtmp->gsmspans; s++) {
 		if (mods & (1 << s)) {
 		    rx_count = ztgsm_ser_rx(gsmtmp, s);
-		    if (debug) 
-			printk(KERN_INFO "ztgsm: RX %d bytes on span %d.\n", rx_count, s);
+		    if (debug > 1) 
+			printk(KERN_INFO "ztgsm: HWIRQ RX %d bytes on span %d.\n", rx_count, s);
 		}
 	    }
-	} else if (ser_status & 0xF00) {
+	}
+	if (ser_status & 0xF00) {
 	    mods = (ser_status & 0xF00) >> 8;
 	    for (s=0; s<gsmtmp->gsmspans; s++) {
 		if (mods & (1 << s)) {
 		    rx_count = ztgsm_ser_rx(gsmtmp, s);
-		    if (debug) 
+//		    if (debug) 
 			printk(KERN_INFO "ztgsm: RX fifo overrun on span %d\n", s);
 		}
 	    }
-	} else if (ser_status & 0xF000) {
+	}
+	if (ser_status & 0xF000) {
 	    mods = (ser_status & 0xF000) >> 12;
 	    for (s=0; s<gsmtmp->gsmspans; s++) {
 		if (mods & (1 << s)) {
@@ -820,10 +934,6 @@
 		    if (debug) 
 			printk(KERN_INFO "ztgsm: TX low water status %#x\n", ser_status);
 		}
-	    }
-	} else {
-	    if (debug) {
-		printk(KERN_INFO "ztgsm: SER_STATUS = %#x\n", ser_status);
 	    }
 	}
     }
@@ -1105,7 +1215,7 @@
 		break;
 	}
 	ztgsm_spans += gsmtmp->gsmspans;
-	
+
 	for (i=0; i < gsmtmp->gsmspans; i++) {
 	    gsmspan = &gsmtmp->gsmspan[i];
 	    ztgsm_init(gsmspan, gsmtmp, i);
@@ -1135,12 +1245,13 @@
 	if (sim) {
 	    ztgsm_switch_off_all(gsmtmp, 0);
 	    printk(KERN_INFO "ztgsm: Initializing SIM extensions...");
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    schedule_timeout((2000 * HZ) / 1000);
 	    ztgsm_switch_on_all(gsmtmp, 0);
 	    printk("done\n");
 	} else {
 	    ztgsm_switch_on_all(gsmtmp, 1);
 	}
-	
 	tmp = pci_get_device(PCI_VENDOR_ID_CCD,pcidid,multi_gsm);
     }
     return 0;
@@ -1182,10 +1293,12 @@
 module_param(debug, int, 0600);
 module_param(pcm_xbar, int, 0600);
 module_param(sim, int, 0600);
+module_param(baudrate, long, 0600);
 #else
 MODULE_PARM(debug,"i");
 MODULE_PARM(pcm_xbar,"i");
 MODULE_PARM(sim,"i");
+MODULE_PARM(baudrate,"l");
 #endif
 
 MODULE_DESCRIPTION("uno/duao/quad GSM zaptel driver");

Modified: zaptel/trunk/kernel/ztgsm/ztgsm.h
URL: http://svn.debian.org/wsvn/pkg-voip/zaptel/trunk/kernel/ztgsm/ztgsm.h?rev=5757&op=diff
==============================================================================
--- zaptel/trunk/kernel/ztgsm/ztgsm.h (original)
+++ zaptel/trunk/kernel/ztgsm/ztgsm.h Wed May 21 00:57:12 2008
@@ -34,8 +34,6 @@
     signed int jitter_offset;
     unsigned long pci_io_phys;
     unsigned int version;
-//    unsigned char *pci_io;
-//    unsigned char *pci_io_phys;
     unsigned long iomem_size;
     unsigned long ioport;
     struct ztgsm_span gsmspan[ztgsm_SPANS];
@@ -47,6 +45,8 @@
     unsigned int ticks;
     unsigned int clicks;
     unsigned int type;
+    unsigned int sim_sel;
+    int ton_off_toggle[ztgsm_SPANS];
     unsigned char rxbuf[ztgsm_SPANS][ZT_CHUNKSIZE];
     unsigned char txbuf[ztgsm_SPANS][ZT_CHUNKSIZE];
     unsigned char drxbuf[ztgsm_SPANS][ztgsm_SER_BUF_SIZE];




More information about the Pkg-voip-commits mailing list