[zaptel-commits] tzafrir: branch 1.2 r1457 - in /branches/1.2/xpp:
./ utils/
zaptel-commits at lists.digium.com
zaptel-commits at lists.digium.com
Sat Sep 9 08:24:13 MST 2006
Author: tzafrir
Date: Sat Sep 9 10:24:12 2006
New Revision: 1457
URL: http://svn.digium.com/view/zaptel?rev=1457&view=rev
Log:
Latest xpp driver. Backported from trunk (r1455, Xorcom r2157)
Added:
branches/1.2/xpp/calibrate_slics (with props)
branches/1.2/xpp/utils/print_modes.c (with props)
Modified:
branches/1.2/xpp/ (props changed)
branches/1.2/xpp/Makefile
branches/1.2/xpp/card_fxo.c
branches/1.2/xpp/card_fxo.h
branches/1.2/xpp/card_fxs.c
branches/1.2/xpp/card_fxs.h
branches/1.2/xpp/init_data_3_19.cmd
branches/1.2/xpp/init_data_3_20.cmd
branches/1.2/xpp/init_data_4_19.cmd
branches/1.2/xpp/init_data_4_20.cmd
branches/1.2/xpp/initialize_registers
branches/1.2/xpp/utils/ (props changed)
branches/1.2/xpp/utils/FPGA_FXS.hex
branches/1.2/xpp/utils/Makefile
branches/1.2/xpp/utils/USB_8613.hex (props changed)
branches/1.2/xpp/utils/fpga_load.c
branches/1.2/xpp/utils/genzaptelconf
branches/1.2/xpp/utils/xpp_fxloader
branches/1.2/xpp/xbus-core.c
branches/1.2/xpp/xbus-core.h
branches/1.2/xpp/xdefs.h
branches/1.2/xpp/xpd.h
branches/1.2/xpp/xpp_usb.c
branches/1.2/xpp/xpp_zap.c
branches/1.2/xpp/xpp_zap.h
branches/1.2/xpp/xproto.c
branches/1.2/xpp/xproto.h
Propchange: branches/1.2/xpp/
------------------------------------------------------------------------------
svk:merge = f558416c-6c06-0410-9f27-dde2687782d0:/trunk/xpp:1453
Propchange: branches/1.2/xpp/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Sat Sep 9 10:24:12 2006
@@ -3,3 +3,5 @@
*.o.cmd
*.ko.cmd
*.mod.c
+.tmp_versions
+.*.swp
Modified: branches/1.2/xpp/Makefile
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/Makefile?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/Makefile (original)
+++ branches/1.2/xpp/Makefile Sat Sep 9 10:24:12 2006
@@ -1,4 +1,4 @@
-EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION -DWITH_RBS
+EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
obj-m = xpp.o xpp_usb.o xpd_fxs.o xpd_fxo.o
xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
Added: branches/1.2/xpp/calibrate_slics
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/calibrate_slics?rev=1457&view=auto
==============================================================================
--- branches/1.2/xpp/calibrate_slics (added)
+++ branches/1.2/xpp/calibrate_slics Sat Sep 9 10:24:12 2006
@@ -1,0 +1,314 @@
+#!/usr/bin/perl -w
+
+#
+# $Id:$
+#
+
+use strict;
+use Time::HiRes qw (time alarm sleep);
+
+my $SlicsFile = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/$ENV{XPD_NAME}/slics";
+
+my @SlicNums = (0 .. 7);
+
+if ( ! -f $SlicsFile ) {
+ exit 1
+}
+
+sub logger($) {
+ print STDERR "LOG: @_\n";
+ system("logger @_");
+}
+
+sub write_to_slic_file($) {
+ my $write_str = shift;
+ #print STDERR "[Writing string]\n".$write_str."[End String]\n";
+
+ open(SLICS,">$SlicsFile") or
+ die("Failed writing to slics file $SlicsFile");
+ print SLICS $write_str;
+ close(SLICS);
+ sleep(0.001);
+
+}
+
+sub read_reg($$$) {
+ my $read_slic = shift;
+ my $read_reg = shift;
+ my $direct = shift;
+
+ write_to_slic_file(
+ sprintf("%02x 00 00 00 R%s %02X",
+ 1<<$read_slic, $direct, $read_reg));
+ sleep(0.001);
+ open(SLICS,$SlicsFile) or
+ die("Failed reading from slics file $SlicsFile");
+ my @reply = ();
+ while(<SLICS>){
+ #if (/^[^#]/) {
+ # print STDERR "answer line: $_";
+ #}
+ if (/^SLIC_REPLY:\s+[DI]\s+reg_num=0x[[:xdigit:]]+,\s+dataH=0x([[:xdigit:]]+)\s+dataL=0x([[:xdigit:]]+)/){
+ @reply = (hex($1), hex($2));
+ #print STDERR "got [@reply]\n";
+ last;
+ }
+ }
+ close(SLICS);
+ if ($direct eq 'I') {
+ return @reply;
+ } else {
+ return $reply[1];
+ }
+}
+
+# TODO: rearange arguments
+sub write_reg{#($$$$$) {
+ my $read_slic = shift;
+ my $read_reg = shift;
+ my $direct = shift;
+ my $reg_val_low = shift;
+ my $reg_val_hi = shift;
+
+ my $str = sprintf "%02x 00 00 00 W%s %02X %02X",
+ 1<<$read_slic, $direct, $read_reg, $reg_val_low;
+ if ($direct eq 'I') {
+ $str .= sprintf " %02X", $reg_val_hi;
+ }
+ #printf STDERR "Writing: $str\n";
+ write_to_slic_file($str);
+}
+
+# TODO: rearange arguments
+sub write_reg_all_slics{#($$$$) {
+ my $read_reg = shift;
+ my $direct = shift;
+ my $reg_val_low = shift;
+ my $reg_val_hi = shift;
+
+ my $str = sprintf "FF FF 00 00 W%s %02X %02X",
+ $direct, $read_reg, $reg_val_low;
+ if ($direct eq 'I') {
+ $str .= sprintf " %02X", $reg_val_hi;
+ }
+ printf STDERR "Writing: $str\n";
+ write_to_slic_file($str);
+}
+
+sub log_calib_params() {
+ for my $i (100 .. 107) {
+ my $line="Calib Reg $i: ";
+ for my $slic (@SlicNums) {
+ $line .= " ".read_reg($slic, $i, 'D');
+ }
+ logger($line);
+ }
+}
+
+sub init_indirect_registers() {
+ return write_to_slic_file("#
+FF FF 00 00 WI 00 C2 55
+FF FF 00 00 WI 01 E6 51
+FF FF 00 00 WI 02 85 4B
+FF FF 00 00 WI 03 37 49
+
+FF FF 00 00 WI 04 33 33
+FF FF 00 00 WI 05 02 02
+FF FF 00 00 WI 06 02 02
+FF FF 00 00 WI 07 98 01
+
+FF FF 00 00 WI 08 98 01
+FF FF 00 00 WI 09 11 06
+FF FF 00 00 WI 0A 02 02
+FF FF 00 00 WI 0B E5 00
+
+FF FF 00 00 WI 0C 1C 0A
+FF FF 00 00 WI 0D 30 7B
+FF FF 00 00 WI 0E 63 00
+FF FF 00 00 WI 0F 00 00
+
+FF FF 00 00 WI 10 70 78
+FF FF 00 00 WI 11 7D 00
+FF FF 00 00 WI 12 00 00
+FF FF 00 00 WI 13 00 00
+
+FF FF 00 00 WI 14 F0 7E
+FF FF 00 00 WI 15 60 01
+FF FF 00 00 WI 16 00 00
+FF FF 00 00 WI 17 00 20
+
+FF FF 00 00 WI 18 00 20
+FF FF 00 00 WI 19 00 00
+FF FF 00 00 WI 1A 00 20
+FF FF 00 00 WI 1B 00 40
+
+FF FF 00 00 WI 1C 00 10
+FF FF 00 00 WI 1D 00 36
+FF FF 00 00 WI 1E 00 10
+FF FF 00 00 WI 1F 00 02
+
+FF FF 00 00 WI 20 C0 07
+FF FF 00 00 WI 21 00 26
+FF FF 00 00 WI 22 F4 0F
+FF FF 00 00 WI 23 00 80
+
+#FF FF 00 00 WI 24 20 03
+#FF FF 00 00 WI 25 8C 08
+#FF FF 00 00 WI 26 00 01
+#FF FF 00 00 WI 27 10 00
+
+FF FF 00 00 WI 24 00 08
+FF FF 00 00 WI 25 00 08
+FF FF 00 00 WI 26 00 08
+FF FF 00 00 WI 27 00 08
+
+FF FF 00 00 WI 28 00 0C
+FF FF 00 00 WI 29 00 0C
+FF FF 00 00 WI 2B 00 01
+
+FF FF 00 00 WI 63 DA 00
+FF FF 00 00 WI 64 60 6B
+FF FF 00 00 WI 65 74 00
+FF FF 00 00 WI 66 C0 79
+
+FF FF 00 00 WI 67 20 11
+FF FF 00 00 WI 68 E0 3B
+#");
+}
+
+sub init_early_direct_regs() {
+ return write_to_slic_file("#
+FF FF 00 00 WD 08 00
+FF FF 00 00 WD 4A 34
+FF FF 00 00 WD 4B 10
+FF FF 00 00 WD 40 00
+#")
+}
+
+my @FilterParams = ();
+
+sub save_indirect_filter_params() {
+ for my $slic (@SlicNums) {
+ for my $reg (35 .. 39) {
+ $FilterParams[$slic][$reg] =
+ [read_reg($slic, $reg, 'I')];
+ write_reg($slic, $reg, 'I', 0, 0x80);
+ }
+ }
+
+}
+
+sub restore_indirect_filter_params() {
+ for my $slic (@SlicNums) {
+ for my $reg (35 .. 39) {
+ write_reg($slic, $reg, 'I',
+ @{$FilterParams[$slic][$reg]});
+ }
+ }
+}
+
+my $ManualCalibrationSleepTime = 0.04; # 40ms
+
+sub manual_calibrate_loop($$) {
+ my $write_reg = shift;
+ my $read_reg = shift;
+
+ # counters to count down to (at most) 0
+ my @slic_counters = ();
+ for my $i (0 .. $#SlicNums) {
+ $slic_counters[$i] = 0x1F;
+ }
+
+ # start calibration:
+ my $calibration_in_progress = 1;
+ write_reg_all_slics($write_reg, 'D', 0x1F);
+ sleep $ManualCalibrationSleepTime;
+
+ # wait until all slics have finished calibration, or for timeout
+ while ($calibration_in_progress) {
+ $calibration_in_progress = 0; # until proven otherwise
+ print STDERR "ManualCalib:: ";
+ for my $slic(@SlicNums) {
+ my $value = read_reg($slic, $read_reg, 'D');
+ print STDERR " [$slic_counters[$slic]:$value]";
+ if ($value != 0 && $slic_counters[$slic] >= 0) {
+ $calibration_in_progress = 1;
+ $slic_counters[$slic]--;
+ write_reg($slic,$write_reg,'D',$slic_counters[$slic]);
+ }
+ }
+ print STDERR "\n";
+ # TODO: unnecessary sleep in the last round:
+ sleep $ManualCalibrationSleepTime;
+ }
+}
+
+sub manual_calibrate() {
+ manual_calibrate_loop(98, 88);
+ manual_calibrate_loop(99, 89);
+}
+
+sub auto_calibrate($$) {
+ my $calib_96 = shift;
+ my $calib_97 = shift;
+
+ #log_calib_params();
+ # start calibration:
+ write_to_slic_file(
+ sprintf
+ "FF FF 00 00 WD 61 %02X\n".
+ "FF FF 00 00 WD 60 %02X\n".
+ "", $calib_97, $calib_96
+
+ );
+ # wait until all slics have finished calibration, or for timeout
+ my $end_time=time() + 2;
+ my $timeout=0;
+ CALIB_LOOP: for my $slic (@SlicNums) {
+ logger("checking slic $slic");
+ while(1) {
+ my $reply;
+ if (($reply=read_reg($slic, 96, 'D')) == 0) {
+ # move to next register
+ logger("slic $slic calibrated");
+ last;
+ }
+ print STDERR "reply: $reply\n";
+ my $time=time();
+ if ( $time > $end_time) {
+ $timeout=1;
+ logger("Exiting on timeout: $time is after timeout $end_time .");
+ exit 1;
+ #last CALIB_LOOP;
+ }
+ logger("auto_calibrate not done yet: slic #$slic\n");
+ sleep(0.1);
+ }
+ }
+ #log_calib_params();
+}
+
+###########################################################
+#
+# main
+#
+
+# TODO: for all slics check the following reads to check communication
+#read_reg($slic, 0x08, 'D'): 0x02
+#read_reg($slic, 0x0B, 'D'): 0x33
+#read_reg($slic, 0x40, 'D'): 0x00 (?)
+
+print STDERR "starting\n";
+
+init_indirect_registers();
+print STDERR "after init_indirect_registers\n";
+init_early_direct_regs();
+print STDERR "after init_early_direct_regs\n";
+auto_calibrate(0x47, 0x1E);
+print STDERR "after auto_calibrate\n";
+manual_calibrate();
+print STDERR "after manul_calibrate\n";
+auto_calibrate(0x40, 0x01);
+print STDERR "after auto_calibrate 2\n";
+
+
Propchange: branches/1.2/xpp/calibrate_slics
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/1.2/xpp/calibrate_slics
------------------------------------------------------------------------------
svn:executable = *
Propchange: branches/1.2/xpp/calibrate_slics
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: branches/1.2/xpp/calibrate_slics
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: branches/1.2/xpp/card_fxo.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/card_fxo.c?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/card_fxo.c (original)
+++ branches/1.2/xpp/card_fxo.c Sat Sep 9 10:24:12 2006
@@ -51,12 +51,14 @@
#define NUM_LEDS 1
#define DELAY_UNTIL_DIALTONE 3000
+#define BAT_THRESHOLD 3
+#define BAT_DEBOUNCE 3 /* compensate for battery voltage fluctuation (in poll_battery_interval's) */
+
/*---------------- FXO Protocol Commands ----------------------------------*/
static /* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on);
static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, int pos);
static /* 0x0F */ DECLARE_CMD(FXO, RING, int pos, bool on);
-static /* 0x0F */ DECLARE_CMD(FXO, SETHOOK, int pos, bool offhook);
static /* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on);
static /* 0x0F */ DECLARE_CMD(FXO, DAA_QUERY, int pos, byte reg_num);
@@ -70,20 +72,49 @@
#define PROC_DAA_FNAME "slics"
#define PROC_FXO_INFO_FNAME "fxo_info"
+#ifdef SOFT_RING
+#define POLL_RING_INTERVAL 2
+#define RING_THRESHOLD 3
+#define NORING_THRESHOLD 10
+#endif
+#define DAA_RING_REGISTER 0x05
+
struct FXO_priv_data {
struct proc_dir_entry *xpd_slic;
struct proc_dir_entry *fxo_info;
+ uint poll_counter;
slic_reply_t requested_reply;
slic_reply_t last_reply;
xpp_line_t battery;
+ ushort battery_debounce[CHANNELS_PERXPD];
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
+ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
int blinking[NUM_LEDS][CHANNELS_PERXPD];
+#ifdef SOFT_RING
+ ushort ring_thresh[CHANNELS_PERXPD];
+ ushort noring_thresh[CHANNELS_PERXPD];
+ /* ring_sig is set when Reg5, bit 2 (Ring Detect) is set.
+ * While ring_sig=1 we check R5 bit 20H and 40H for ringing.
+ * When it drops to 0 that's the end of the ring sequence and
+ * we clear the ring detection variables */
+ ushort ring_sig[CHANNELS_PERXPD];
+#endif
};
/*---------------- FXO: Static functions ----------------------------------*/
#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
-#define DO_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
+#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
+
+void MARK_LED(xpd_t *xpd, lineno_t pos, byte color, bool on)
+{
+ struct FXO_priv_data *priv = xpd->priv;
+
+ if(on)
+ BIT_SET(priv->ledcontrol[color], pos);
+ else
+ BIT_CLR(priv->ledcontrol[color], pos);
+}
/*
* LED control is done via DAA register 0x20
@@ -130,10 +161,10 @@
static void handle_fxo_leds(xpd_t *xpd)
{
- int i;
- unsigned long flags;
+ int i;
+ unsigned long flags;
const enum fxo_leds color = LED_GREEN;
- unsigned int timer_count;
+ unsigned int timer_count;
struct FXO_priv_data *priv;
BUG_ON(!xpd);
@@ -146,7 +177,7 @@
if(IS_BLINKING(priv,i,color)) {
// led state is toggled
if((timer_count % LED_BLINK_PERIOD) == 0) {
- DBG("%s/%s/%d: led_state=%s\n", xpd->xbus->busname, xpd->xpdname, i,
+ DBG("%s/%s/%d: ledstate=%s\n", xpd->xbus->busname, xpd->xpdname, i,
(IS_SET(priv->ledstate[color], i))?"ON":"OFF");
if(!IS_SET(priv->ledstate[color], i)) {
do_led(xpd, i, color, 1);
@@ -154,35 +185,78 @@
do_led(xpd, i, color, 0);
}
}
+ } else if(IS_SET(priv->ledcontrol[color], i) && !IS_SET(priv->ledstate[color], i)) {
+ do_led(xpd, i, color, 1);
+ } else if(!IS_SET(priv->ledcontrol[color], i) && IS_SET(priv->ledstate[color], i)) {
+ do_led(xpd, i, color, 0);
}
}
spin_unlock_irqrestore(&xpd->lock, flags);
}
-static void do_sethook(xpd_t *xpd, int pos, bool offhook)
+static void mark_ring(xpd_t *xpd, lineno_t pos, bool on)
+{
+ struct FXO_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ if(on && !xpd->ringing[pos]) {
+ DBG("%s/%s/%d: START\n", xpd->xbus->busname, xpd->xpdname, pos);
+ xpd->ringing[pos] = 1;
+ MARK_BLINK(priv, pos, LED_GREEN, LED_BLINK);
+ update_zap_ring(xpd, pos, 1);
+ } else if(!on && xpd->ringing[pos]) {
+ DBG("%s/%s/%d: STOP\n", xpd->xbus->busname, xpd->xpdname, pos);
+ xpd->ringing[pos] = 0;
+ if(IS_BLINKING(priv, pos, LED_GREEN))
+ MARK_BLINK(priv, pos, LED_GREEN, 0);
+ update_zap_ring(xpd, pos, 0);
+ }
+}
+
+static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
{
unsigned long flags;
- struct FXO_priv_data *priv;
+ xbus_t *xbus;
+ struct FXO_priv_data *priv;
+ int ret = 0;
+ bool value;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
BUG_ON(!xpd);
BUG_ON(xpd->direction == TO_PHONE); // We can SETHOOK state only on PSTN
+ xbus = xpd->xbus;
priv = xpd->priv;
BUG_ON(!priv);
if(!IS_SET(priv->battery, pos)) {
- DBG("%s/%s/%d: WARNING: called while battery is off\n", xpd->xbus->busname, xpd->xpdname, pos);
+ NOTICE("%s/%s/%d: WARNING: called while battery is off\n", xbus->busname, xpd->xpdname, pos);
}
spin_lock_irqsave(&xpd->lock, flags);
- xpd->ringing[pos] = 0; // No more rings
- CALL_XMETHOD(SETHOOK, xpd->xbus, xpd, pos, offhook);
- if(offhook) {
- BIT_SET(xpd->hookstate, pos);
+ mark_ring(xpd, pos, 0); // No more rings
+ value = (to_offhook) ? 0x09 : 0x08; /* Bit 3 is for CID */
+ DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (to_offhook)?"OFFHOOK":"ONHOOK");
+ MARK_LED(xpd, pos, LED_GREEN, (to_offhook)?LED_ON:LED_OFF);
+ XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, BIT(pos), DAA_RING_REGISTER, value);
+ pack->datalen = len;
+ packet_send(xbus, pack);
+#ifdef SOFT_RING
+ priv->ring_sig[pos] = 0;
+#endif
+ if(to_offhook) {
+ BIT_SET(xpd->offhook, pos);
} else {
- BIT_CLR(xpd->hookstate, pos);
+ BIT_CLR(xpd->offhook, pos);
+ BIT_CLR(xpd->cid_on, pos);
xpd->delay_until_dialtone[pos] = 0;
}
spin_unlock_irqrestore(&xpd->lock, flags);
- if(offhook)
+ if(to_offhook)
wake_up_interruptible(&xpd->txstateq[pos]);
+ return ret;
}
/*---------------- FXO: Methods -------------------------------------------*/
@@ -282,7 +356,6 @@
xbus_t *xbus;
struct FXO_priv_data *priv;
int i;
- unsigned long flags;
BUG_ON(!xpd);
xbus = xpd->xbus;
@@ -300,11 +373,9 @@
cur_chan->pvt = xpd;
cur_chan->sigcap = FXO_DEFAULT_SIGCAP;
}
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
- for_each_line(xpd, i) {
- do_led(xpd, i, LED_GREEN, LED_ON);
+ MARK_LED(xpd, ALL_LINES, LED_GREEN, LED_OFF);
+ for_each_line(xpd, i) {
+ MARK_LED(xpd, i, LED_GREEN, LED_ON);
mdelay(50);
}
return 0;
@@ -323,13 +394,12 @@
BUG_ON(!priv);
DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
for_each_line(xpd, i) {
- do_led(xpd, i, LED_GREEN, LED_OFF);
+ MARK_LED(xpd, i, LED_GREEN, LED_OFF);
mdelay(50);
}
return 0;
}
-#ifdef WITH_RBS
int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
{
struct FXO_priv_data *priv;
@@ -355,43 +425,6 @@
return 0;
}
-#else
-int FXO_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
-{
- int ret = 0;
- struct FXO_priv_data *priv;
-
- DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, hookstate2str(hookstate));
- switch(hookstate) {
- /* On-hook, off-hook: The PBX is playing a phone on an FXO line. */
- case ZT_ONHOOK:
- do_sethook(xpd, pos, 0);
- break;
- case ZT_START:
- DBG("%s/%s/%d: fall through ZT_OFFHOOK\n", xbus->busname, xpd->xpdname, pos);
- xpd->delay_until_dialtone[pos] = DELAY_UNTIL_DIALTONE;
- // Fall through
- case ZT_OFFHOOK:
- do_sethook(xpd, pos, 1);
- wait_event_interruptible(xpd->txstateq[pos], xpd->delay_until_dialtone[pos] <= 0);
- break;
- case ZT_WINK:
- WARN("No code yet\n");
- break;
- case ZT_FLASH:
- WARN("No code yet\n");
- break;
- case ZT_RING:
- DBG("%s/%s/%d: ZT_RING: %d\n", xbus->busname, xpd->xpdname, pos, xpd->ringing[pos]);
- break;
- case ZT_RINGOFF:
- WARN("No code yet\n");
- break;
- }
- return ret;
-}
-#endif
-
static void poll_battery(xbus_t *xbus, xpd_t *xpd)
{
int i;
@@ -401,20 +434,37 @@
}
}
+#ifdef SOFT_RING
+static void poll_ring(xbus_t *xbus, xpd_t *xpd)
+{
+ int i;
+ struct FXO_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ for_each_line(xpd, i) {
+ if(priv->ring_sig[i])
+ CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_RING_REGISTER);
+ }
+}
+#endif
static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd)
{
- static unsigned rate_limit = 0;
struct FXO_priv_data *priv;
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- rate_limit++;
- if(poll_battery_interval != 0 && (rate_limit % poll_battery_interval) == 0) {
+ if(poll_battery_interval != 0 && (priv->poll_counter % poll_battery_interval) == 0) {
poll_battery(xbus, xpd);
}
+#ifdef SOFT_RING
+ if((priv->poll_counter % POLL_RING_INTERVAL) == 0)
+ poll_ring(xbus, xpd);
+#endif
handle_fxo_leds(xpd);
+ priv->poll_counter++;
return 0;
}
@@ -433,13 +483,13 @@
int i,ret;
BUG_ON(!xpd);
- DBG("cmd: 0x%x, expecting: 0x%x, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos);
+ DBG("cmd: 0x%X, expecting: 0x%X, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos);
switch (cmd) {
case WCTDM_SET_ECHOTUNE:
DBG("-- Setting echo registers: \n");
/* first off: check if this span is fxs. If not: -EINVALID */
if (copy_from_user(&echoregs.wctdm_struct,
- (struct wctdm_echo_coefs*)arg, sizeof(echoregs.wctdm_struct)))
+ (struct wctdm_echo_coefs __user *)arg, sizeof(echoregs.wctdm_struct)))
return -EFAULT;
/* Set the ACIM register */
@@ -474,7 +524,6 @@
static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
{
- unsigned long flags;
int ret = 0;
int i;
@@ -486,15 +535,11 @@
DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
if(on) {
for_each_line(xpd, i) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, i, LED_GREEN, LED_ON);
- spin_unlock_irqrestore(&xpd->lock, flags);
+ MARK_LED(xpd, i, LED_GREEN, LED_ON);
mdelay(20);
}
for_each_line(xpd, i) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, i, LED_GREEN, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
+ MARK_LED(xpd, i, LED_GREEN, LED_OFF);
mdelay(20);
}
}
@@ -539,31 +584,6 @@
return ret;
}
-static /* 0x0F */ HOSTCMD(FXO, SETHOOK, int pos, bool offhook)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
- unsigned long flags;
- bool value;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- value = (offhook) ? 0x09 : 0x08;
- // value |= BIT(3); /* Bit 3 is for CID */
- DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (offhook)?"OFFHOOK":"ONHOOK");
- spin_lock_irqsave(&xpd->lock, flags);
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, BIT(pos), 0x05, value);
- pack->datalen = len;
- packet_send(xbus, pack);
- do_led(xpd, pos, LED_GREEN, (offhook)?LED_ON:LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
- return ret;
-}
-
static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
{
return -ENOSYS;
@@ -597,19 +617,39 @@
xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXO, SIG_CHANGED, sig_toggles);
unsigned long flags;
int i;
+ struct FXO_priv_data *priv;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
__FUNCTION__, cmd->name, XPD_NUM(pack->content.addr));
return -EPROTO;
}
+ priv = xpd->priv;
+ BUG_ON(!priv);
DBG("%s/%s: (PSTN) sig_toggles=0x%04X sig_status=0x%04X\n", xpd->xbus->busname, xpd->xpdname, sig_toggles, sig_status);
spin_lock_irqsave(&xpd->lock, flags);
for_each_line(xpd, i) {
- if(IS_SET(sig_status, i)) {
- xpd->ringing[i] = 1;
- } else {
- xpd->ringing[i] = 0;
+ if(IS_SET(sig_toggles, i)) {
+ if(!IS_SET(priv->battery, i)) {
+ DBG("%s/%s/%d: battery is off. ignore false alarm.\n",
+ xbus->busname, xpd->xpdname, i);
+ continue;
+ }
+ if(IS_SET(sig_status, i)) {
+#ifdef SOFT_RING
+ priv->ring_sig[i]=1; /* trigger register polling */
+ /* reset ring check counters */
+ priv->ring_thresh[i] = 0;
+ priv->noring_thresh[i] = 0;
+#else
+ mark_ring(xpd, i, 1);
+#endif
+ } else {
+#ifdef SOFT_RING
+ priv->ring_sig[i] = 0;
+#endif
+ mark_ring(xpd, i, 0);
+ }
}
}
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -632,25 +672,58 @@
priv = xpd->priv;
BUG_ON(!priv);
if(!info->indirect && info->reg_num == DAA_VBAT_REGISTER) {
- xpp_line_t last_batt_on = priv->battery;
- xpp_line_t changed_lines;
+ byte bat = abs((signed char)info->data_low);
int i;
- if(abs(info->data_low) < BAT_THRESHOLD) {
- priv->battery &= ~lines;
- // DBG("%s/%s: BATTERY OFF (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, info->data_low);
- } else {
- priv->battery |= lines;
- // DBG("%s/%s: BATTERY ON (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, info->data_low);
- }
- changed_lines = last_batt_on ^ priv->battery;
for_each_line(xpd, i) {
- if(IS_SET(changed_lines, i)) {
- update_line_status(xpd, i, IS_SET(priv->battery, i));
+ if(!IS_SET(lines, i))
+ continue;
+ if(bat < BAT_THRESHOLD) {
+ /*
+ * Check for battery voltage fluctuations
+ */
+ if(IS_SET(priv->battery, i) && priv->battery_debounce[i]++ > BAT_DEBOUNCE) {
+ DBG("%s/%s: BATTERY OFF (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
+ BIT_CLR(priv->battery, i);
+ update_line_status(xpd, i, 0);
+ }
+ } else {
+ priv->battery_debounce[i] = 0;
+ if(!IS_SET(priv->battery, i)) {
+ DBG("%s/%s: BATTERY ON (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
+ BIT_SET(priv->battery, i);
+ }
}
}
}
+#ifdef SOFT_RING
+ if(!info->indirect && info->reg_num == DAA_RING_REGISTER) {
+ bool ringit = (info->data_low & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
+ int i;
+
+ for_each_line(xpd, i) {
+ if(!IS_SET(lines, i))
+ continue;
+ if (!priv->ring_sig[i])
+ continue;
+ if(ringit) {
+ if(priv->ring_thresh[i] > RING_THRESHOLD) {
+ mark_ring(xpd, i, 1);
+ priv->noring_thresh[i] = 0;
+ } else
+ priv->ring_thresh[i]++;
+ } else {
+ if(priv->noring_thresh[i] > NORING_THRESHOLD) {
+ mark_ring(xpd, i, 0);
+ priv->ring_thresh[i] = 0;
+ } else
+ priv->noring_thresh[i]++;
+ }
+ }
+ }
+#endif
#if 0
+ if (info->reg_num != 29)
DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
xpd->id, (info->indirect)?"I":"D",
info->reg_num, info->data_low, info->data_high);
@@ -681,16 +754,11 @@
.card_remove = FXO_card_remove,
.card_zaptel_preregistration = FXO_card_zaptel_preregistration,
.card_zaptel_postregistration = FXO_card_zaptel_postregistration,
-#ifdef WITH_RBS
.card_hooksig = FXO_card_hooksig,
-#else
- .card_sethook = FXO_card_sethook,
-#endif
.card_tick = FXO_card_tick,
.card_ioctl = FXO_card_ioctl,
.RING = XPROTO_CALLER(FXO, RING),
- .SETHOOK = XPROTO_CALLER(FXO, SETHOOK),
.RELAY_OUT = XPROTO_CALLER(FXO, RELAY_OUT),
.CHAN_ENABLE = XPROTO_CALLER(FXO, CHAN_ENABLE),
.CHAN_CID = XPROTO_CALLER(FXO, CHAN_CID),
@@ -734,21 +802,47 @@
len += sprintf(page + len, "\t%-17s: ", "Channel");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", i % 10);
+ len += sprintf(page + len, "%2d ", i % 10);
}
len += sprintf(page + len, "\n\t%-17s: ", "ledstate");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", IS_SET(priv->ledstate[LED_GREEN], i));
+ len += sprintf(page + len, "%2d ", IS_SET(priv->ledstate[LED_GREEN], i));
+ }
+ len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol");
+ for_each_line(xpd, i) {
+ if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
+ len += sprintf(page + len, "%2d ", IS_SET(priv->ledcontrol[LED_GREEN], i));
}
len += sprintf(page + len, "\n\t%-17s: ", "blinking");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", IS_BLINKING(priv,i,LED_GREEN));
- }
+ len += sprintf(page + len, "%2d ", IS_BLINKING(priv,i,LED_GREEN));
+ }
+#ifdef SOFT_RING
+ len += sprintf(page + len, "\n\t%-17s: ", "ring_thresh");
+ for_each_line(xpd, i) {
+ if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
+ len += sprintf(page + len, "%2d ", priv->ring_thresh[i]);
+ }
+ len += sprintf(page + len, "\n\t%-17s: ", "noring_thresh");
+ for_each_line(xpd, i) {
+ if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
+ len += sprintf(page + len, "%2d ", priv->noring_thresh[i]);
+ }
+ len += sprintf(page + len, "\n\t%-17s: ", "ring_sig");
+ for_each_line(xpd, i) {
+ if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
+ len += sprintf(page + len, "%d ", priv->ring_sig[i]);
+ }
+#endif
len += sprintf(page + len, "\n\t%-17s: ", "battery");
for_each_line(xpd, i) {
- len += sprintf(page + len, "%d ", IS_SET(priv->battery, i));
+ len += sprintf(page + len, "%2d ", IS_SET(priv->battery, i));
+ }
+ len += sprintf(page + len, "\n\t%-17s: ", "battery_debounce");
+ for_each_line(xpd, i) {
+ len += sprintf(page + len, "%2d ", priv->battery_debounce[i]);
}
len += sprintf(page + len, "\n");
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -896,8 +990,7 @@
static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
- const int LINE_LEN = 500;
- char buf[LINE_LEN];
+ char buf[MAX_PROC_WRITE];
char *p;
int i;
int ret;
@@ -905,7 +998,7 @@
if(!xpd)
return -ENODEV;
for(i = 0; i < count; /* noop */) {
- for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
+ for(p = buf; p < buf + MAX_PROC_WRITE; p++) { /* read a line */
if(i >= count)
break;
if(get_user(*p, buffer + i))
@@ -914,7 +1007,7 @@
if(*p == '\n' || *p == '\r') /* whatever */
break;
}
- if(p >= buf + LINE_LEN)
+ if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
ret = process_slic_cmdline(xpd, buf);
@@ -929,6 +1022,11 @@
int __init card_fxo_startup(void)
{
INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION);
+#ifdef SOFT_RING
+ INFO("FEATURE: %s with SOFT_RING\n", THIS_MODULE->name);
+#else
+ INFO("FEATURE: %s without SOFT_RING\n", THIS_MODULE->name);
+#endif
xproto_register(&PROTO_TABLE(FXO));
return 0;
}
Modified: branches/1.2/xpp/card_fxo.h
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/card_fxo.h?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/card_fxo.h (original)
+++ branches/1.2/xpp/card_fxo.h Sat Sep 9 10:24:12 2006
@@ -32,7 +32,6 @@
XPROTO_NAME(FXO, CHAN_ENABLE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RING) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, SETHOOK) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RELAY_OUT) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, DAA_INIT) = 0x0F, /* Write to DAA */
@@ -56,6 +55,5 @@
);
#define DAA_VBAT_REGISTER 29
-#define BAT_THRESHOLD 3
#endif /* CARD_FXO_H */
Modified: branches/1.2/xpp/card_fxs.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/card_fxs.c?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/card_fxs.c (original)
+++ branches/1.2/xpp/card_fxs.c Sat Sep 9 10:24:12 2006
@@ -77,7 +77,6 @@
static /* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, int pos);
static /* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, SETHOOK, int pos, bool offhook);
static /* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on);
static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
@@ -326,17 +325,8 @@
/*
* Setup ring timers
*/
-#ifdef WITH_RBS
/* Software controled ringing (for CID) */
ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x00); /* Ringing Oscilator Control */
-#else
- /* Hardware controled ringing (no CID) */
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x30, 0x80); /* Active timer low byte */
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x31, 0x3E); /* Active timer high byte */
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x32, 0x80); /* Inactive timer low byte */
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x33, 0x3E); /* Inactive timer high byte */
- ret += SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x18); /* Ringing Oscilator Control */
-#endif
if(ret < 0)
goto err;
DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
@@ -418,7 +408,6 @@
return 0;
}
-#ifdef WITH_RBS
int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
{
int ret = 0;
@@ -490,74 +479,6 @@
return ret;
}
-#else
-int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
-{
- int ret = 0;
-
- DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, hookstate2str(hookstate));
- switch(hookstate) {
- /* On-hook, off-hook: The PBX is playing a phone on an FXO line.
- * Can be ignored for an FXS line
- */
- case ZT_ONHOOK:
- if(IS_SET(xpd->digital_inputs, pos)) {
- NOTICE("%s: Trying to ONHOOK a digital input channel %d. Ignoring\n", __FUNCTION__, pos);
- ret = -EINVAL;
- break;
- }
- if(IS_SET(xpd->digital_outputs, pos)) {
- DBG("%s/%s/%d: digital output OFF\n", xbus->busname, xpd->xpdname, pos);
- ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 0);
- break;
- }
- xpd->ringing[pos] = 0;
- DBG("%s/%s/%d: stop ringing\n", xbus->busname, xpd->xpdname, pos);
-#if 1 // FIXME: Not needed -- verify
- ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off
-#endif
- if(ret) {
- DBG("ZT_ONHOOK(stop ring) Failed: ret=0x%02X\n", ret);
- break;
- }
- break;
- case ZT_START:
- DBG("%s/%s/%d: fall through ZT_OFFHOOK\n", xbus->busname, xpd->xpdname, pos);
- // Fall through
- case ZT_OFFHOOK:
- DBG("%s/%s/%d: ZT_OFFHOOK (ignoring for PHONES)\n", xbus->busname, xpd->xpdname, pos);
- break;
- case ZT_WINK:
- WARN("No code yet\n");
- break;
- case ZT_FLASH:
- WARN("No code yet\n");
- break;
- case ZT_RING:
- DBG("%s/%s/%d: ZT_RING: %d\n", xbus->busname, xpd->xpdname, pos, xpd->ringing[pos]);
- if(IS_SET(xpd->digital_inputs, pos)) {
- NOTICE("%s: Trying to RING a digital input channel %d. Ignoring\n", __FUNCTION__, pos);
- return -EINVAL;
- }
- if(IS_SET(xpd->digital_outputs, pos)) {
- DBG("%s/%s/%d: digital output ON\n", xbus->busname, xpd->xpdname, pos);
- ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1);
- return ret;
- }
- xpd->ringing[pos] = 1;
- ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on
- if(ret) {
- DBG("ZT_RING Failed: ret=0x%02X\n", ret);
- }
- break;
- case ZT_RINGOFF:
- WARN("No code yet\n");
- break;
- }
- return ret;
-}
-#endif
-
/*
* INPUT polling is done via SLIC register 0x06 (same as LEDS):
* 7 6 5 4 3 2 1 0
@@ -698,12 +619,6 @@
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, SETHOOK, int pos, bool offhook)
-{
- BUG(); // Should never be called
- return 0;
-}
-
static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
{
int ret = 0;
@@ -775,21 +690,17 @@
if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
continue;
if(IS_SET(sig_toggles, i)) {
- struct zt_chan *chan = &xpd->span.chans[i];
-
xpd->ringing[i] = 0; // No more ringing...
do_chan_power(xpd->xbus, xpd, BIT(i), 0); // When not ringing, VBAT is always Low
MARK_BLINK(priv,i,LED_GREEN,0);
if(IS_SET(sig_status, i)) {
- DBG("OFFHOOK: channo=%d\n", chan->channo);
+ DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i);
MARK_LED(priv,i,LED_GREEN,LED_ON);
- BIT_SET(xpd->hookstate, i);
- zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
+ update_line_status(xpd, i, 1);
} else {
- DBG("ONHOOK channo=%d\n", chan->channo);
+ DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, i);
MARK_LED(priv,i,LED_GREEN,LED_OFF);
- BIT_CLR(xpd->hookstate, i);
- zt_hooksig(chan, ZT_RXSIG_ONHOOK);
+ update_line_status(xpd, i, 0);
}
}
}
@@ -824,27 +735,22 @@
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
int channo = input_channels[i];
int newchanno;
- struct zt_chan *chan;
if(IS_SET(lines, channo)) {
newchanno = LINES_REGULAR + LINES_DIGI_OUT + i;
BIT_CLR(lines, channo);
BIT_SET(lines, newchanno);
- chan = &xpd->span.chans[newchanno];
xpd->ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs.
- if(offhook && !IS_SET(xpd->hookstate, newchanno)) { // OFFHOOK
- DBG("OFFHOOK: channo=%d\n", chan->channo);
- BIT_SET(xpd->hookstate, newchanno);
- zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
- } else if(!offhook && IS_SET(xpd->hookstate, newchanno)) { // ONHOOK
- DBG("ONHOOK channo=%d\n", chan->channo);
- BIT_CLR(xpd->hookstate, newchanno);
- zt_hooksig(chan, ZT_RXSIG_ONHOOK);
+ if(offhook && !IS_SET(xpd->offhook, newchanno)) { // OFFHOOK
+ DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, newchanno);
+ update_line_status(xpd, newchanno, 1);
+ } else if(!offhook && IS_SET(xpd->offhook, newchanno)) { // ONHOOK
+ DBG("%s/%s/%d: ONHOOK\n", xbus->busname, xpd->xpdname, newchanno);
+ update_line_status(xpd, newchanno, 0);
}
}
}
}
-
/* Update /proc info only if reply relate to the last slic read request */
if(priv->requested_reply.indirect == info->indirect &&
priv->requested_reply.reg_num == info->reg_num) {
@@ -869,15 +775,10 @@
.card_remove = FXS_card_remove,
.card_zaptel_preregistration = FXS_card_zaptel_preregistration,
.card_zaptel_postregistration = FXS_card_zaptel_postregistration,
-#ifdef WITH_RBS
.card_hooksig = FXS_card_hooksig,
-#else
- .card_sethook = FXS_card_sethook,
-#endif
.card_tick = FXS_card_tick,
.RING = XPROTO_CALLER(FXS, RING),
- .SETHOOK = XPROTO_CALLER(FXS, SETHOOK),
.RELAY_OUT = XPROTO_CALLER(FXS, RELAY_OUT),
.CHAN_ENABLE = XPROTO_CALLER(FXS, CHAN_ENABLE),
.CHAN_CID = XPROTO_CALLER(FXS, CHAN_CID),
@@ -1088,8 +989,7 @@
static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
- const int LINE_LEN = 500;
- char buf[LINE_LEN];
+ char buf[MAX_PROC_WRITE];
char *p;
int i;
int ret;
@@ -1097,7 +997,7 @@
if(!xpd)
return -ENODEV;
for(i = 0; i < count; /* noop */) {
- for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
+ for(p = buf; p < buf + MAX_PROC_WRITE; p++) { /* read a line */
if(i >= count)
break;
if(get_user(*p, buffer + i))
@@ -1106,7 +1006,7 @@
if(*p == '\n' || *p == '\r') /* whatever */
break;
}
- if(p >= buf + LINE_LEN)
+ if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
ret = process_slic_cmdline(xpd, buf);
Modified: branches/1.2/xpp/card_fxs.h
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/card_fxs.h?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/card_fxs.h (original)
+++ branches/1.2/xpp/card_fxs.h Sat Sep 9 10:24:12 2006
@@ -33,7 +33,6 @@
XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RING) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, SETHOOK) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RELAY_OUT) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, SLIC_INIT) = 0x0F, /* Write to SLIC */
Modified: branches/1.2/xpp/init_data_3_19.cmd
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/init_data_3_19.cmd?rev=1457&r1=1456&r2=1457&view=diff
==============================================================================
--- branches/1.2/xpp/init_data_3_19.cmd (original)
+++ branches/1.2/xpp/init_data_3_19.cmd Sat Sep 9 10:24:12 2006
@@ -17,14 +17,15 @@
;
; SLICS CMD Reg High Low
-; ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
+; -------------------------------------- 8-channel FXS unit initialization
; INTERNAL PS
-; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid data collision), Voltage sense
+; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid
+; data collision), Voltage sense
FF 00 00 00 WD 40 00
FF 00 00 00 WD 6C 01
-; ------------------------------------- Initialization of indirect registers ------------------------------------------
+; ------------------------------------- Initialization of indirect registers
[... 3089 lines stripped ...]
More information about the zaptel-commits
mailing list