summaryrefslogtreecommitdiff
path: root/xpp/card_fxs.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_fxs.c')
-rw-r--r--xpp/card_fxs.c339
1 files changed, 219 insertions, 120 deletions
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c
index d2413f3..41b503e 100644
--- a/xpp/card_fxs.c
+++ b/xpp/card_fxs.c
@@ -34,15 +34,21 @@
static const char rcsid[] = "$Id$";
DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
+DEF_PARM(bool, poll_digital_inputs, 1, "Poll Digital Inputs"); /* must be before zap_debug.h */
+
+/* Signaling is opposite (fxo signalling for fxs card) */
+#if 1
+#define FXS_DEFAULT_SIGCAP (ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS)
+#else
+#define FXS_DEFAULT_SIGCAP (ZT_SIG_SF | ZT_SIG_EM)
+#endif
#define LINES_REGULAR 8
#define LINES_DIGI_OUT 2
#define LINES_DIGI_INP 4
-#define MASK_BITS(b) ((1U << (b)) - 1)
-
-#define MASK_DIGI_OUT (MASK_BITS(LINES_DIGI_OUT) << LINES_REGULAR)
-#define MASK_DIGI_INP (MASK_BITS(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
+#define MASK_DIGI_OUT (BITMASK(LINES_DIGI_OUT) << LINES_REGULAR)
+#define MASK_DIGI_INP (BITMASK(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
enum fxs_leds {
LED_GREEN,
@@ -52,14 +58,27 @@ enum fxs_leds {
#define NUM_LEDS 2
+static int SLIC_DIRECT_REQUEST(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte reg, byte dL)
+{
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, lines, reg, dL);
+ pack->datalen = len;
+ packet_send(xbus, pack);
+ return 0;
+}
+
/*---------------- FXS Protocol Commands ----------------------------------*/
static /* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, xpp_line_t lines);
+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_INIT);
static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
static bool fxs_packet_is_valid(xpacket_t *pack);
@@ -68,26 +87,6 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-#define S_(s,l,...) \
- { \
- .lines = s, \
- { \
- .len = l, \
- .data = { __VA_ARGS__ }, \
- } \
- }
-struct slic_init_data {
- xpp_line_t lines;
- slic_data_t slic_data;
-} slic_init_data[] = {
-#ifdef OLD_CARD
-#include "init_data_3_19.inc"
-#else
-#include "init_data_3_20.inc"
-#endif
-};
-#undef S_
-
#define PROC_SLIC_FNAME "slics"
#define PROC_FXS_INFO_FNAME "fxs_info"
@@ -111,7 +110,6 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on)
BUG_ON(!xbus);
BUG_ON(!xpd);
- lines &= xpd->enabled_chans; // Ignore disabled channels
if(!lines) {
return 0;
}
@@ -132,8 +130,8 @@ static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on)
}
#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
-#define DO_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
-#define DO_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos)))
+#define MARK_BLINK(priv,pos,color,val) ((priv)->blinking[color][pos] = (val))
+#define MARK_LED(priv,pos,color,val) ((val)?BIT_SET((priv)->ledcontrol[color],(pos)):BIT_CLR((priv)->ledcontrol[color],(pos)))
/*
* LED and RELAY control is done via SLIC register 0x06:
@@ -195,7 +193,7 @@ static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on)
BIT_CLR(priv->ledstate[which], pos);
}
}
- if(!(lines & xpd->enabled_chans)) // Ignore disabled channels
+ if(!lines) // Nothing to do
goto out;
DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
value = BIT(2) | BIT(3);
@@ -222,11 +220,11 @@ static void handle_fxs_leds(xpd_t *xpd)
struct FXS_priv_data *priv;
BUG_ON(!xpd);
- priv = xpd->priv;
spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
timer_count = xpd->timer_count;
for(color = 0; color < ARRAY_SIZE(colors); color++) {
- for_each_enabled_line(xpd, i) {
+ for_each_line(xpd, i) {
if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
continue;
if(IS_BLINKING(priv, i, color)) { // Blinking
@@ -282,6 +280,7 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
#ifdef CONFIG_PROC_FS
if(priv->xpd_slic) {
DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname);
+ priv->xpd_slic->data = NULL;
remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir);
}
if(priv->fxs_info) {
@@ -304,31 +303,45 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
if(!priv->fxs_info) {
ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXS_INFO_FNAME, xbus->busname, xpd->xpdname);
ret = -ENOENT;
- goto out;
+ goto err;
}
+ priv->fxs_info->owner = THIS_MODULE;
DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname);
priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir);
if(!priv->xpd_slic) {
ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname);
ret = -ENOENT;
- goto out;
+ goto err;
}
+ priv->xpd_slic->owner = THIS_MODULE;
priv->xpd_slic->write_proc = proc_xpd_slic_write;
priv->xpd_slic->read_proc = proc_xpd_slic_read;
priv->xpd_slic->data = xpd;
#endif
-#ifdef HARD_CODED_INIT
- CALL_PROTO(FXS, SLIC_INIT, xbus, xpd);
-#else
ret = run_initialize_registers(xpd);
+ if(ret < 0)
+ goto err;
+ /*
+ * 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
-out:
- if(ret < 0) {
- clean_proc(xbus, xpd);
- ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
- } else {
- DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
- }
+ if(ret < 0)
+ goto err;
+ DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
+ return 0;
+err:
+ clean_proc(xbus, xpd);
+ ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
return ret;
}
@@ -343,46 +356,139 @@ static int FXS_card_remove(xbus_t *xbus, xpd_t *xpd)
return 0;
}
-static int FXS_card_zaptel_registration(xpd_t *xpd, bool on)
+static int FXS_card_zaptel_preregistration(xpd_t *xpd, bool on)
{
xbus_t *xbus;
struct FXS_priv_data *priv;
+ int i;
unsigned long flags;
- int i;
+ const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
BUG_ON(!xpd);
xbus = xpd->xbus;
- priv = xpd->priv;
BUG_ON(!xbus);
- DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off");
- if(on) {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
- for_each_enabled_line(xpd, i) {
- DO_LED(priv,i,LED_GREEN,LED_ON);
- mdelay(50);
- }
- for_each_enabled_line(xpd, i) {
- DO_LED(priv,i,LED_GREEN,LED_OFF);
- mdelay(50);
- }
- } else {
- spin_lock_irqsave(&xpd->lock, flags);
- do_led(xpd, ALL_LINES, LED_RED, LED_OFF);
- spin_unlock_irqrestore(&xpd->lock, flags);
- for_each_enabled_line(xpd, i) {
- DO_LED(priv,i,LED_RED,LED_ON);
- mdelay(50);
- }
- for_each_enabled_line(xpd, i) {
- DO_LED(priv,i,LED_RED,LED_OFF);
- mdelay(50);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
+ snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: FXS", xbus->num, xpd->id);
+ for_each_line(xpd, i) {
+ struct zt_chan *cur_chan = &xpd->chans[i];
+
+ DBG("setting FXS channel %d\n", i);
+ if(IS_SET(xpd->digital_outputs, i)) {
+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d/%d/%d", xbus->num, xpd->id, i);
+ } else if(IS_SET(xpd->digital_inputs, i)) {
+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d/%d/%d", xbus->num, xpd->id, i);
+ } else {
+ snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXS/%d/%d/%d", xbus->num, xpd->id, i);
}
+ cur_chan->chanpos = i + 1;
+ cur_chan->pvt = xpd;
+ cur_chan->sigcap = FXS_DEFAULT_SIGCAP;
+ }
+ spin_lock_irqsave(&xpd->lock, flags);
+ do_led(xpd, ALL_LINES, color, LED_OFF);
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ for_each_line(xpd, i) {
+ MARK_LED(priv, i, color, LED_ON);
+ mdelay(50);
}
return 0;
}
+static int FXS_card_zaptel_postregistration(xpd_t *xpd, bool on)
+{
+ xbus_t *xbus;
+ struct FXS_priv_data *priv;
+ int i;
+ const enum fxs_leds color = (on) ? LED_GREEN : LED_RED;
+
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ BUG_ON(!xbus);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
+ for_each_line(xpd, i) {
+ MARK_LED(priv, i, color, LED_OFF);
+ mdelay(50);
+ }
+ return 0;
+}
+
+#ifdef WITH_RBS
+int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+{
+ int ret = 0;
+
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+ BUG_ON(xpd->direction != TO_PHONE);
+ if (IS_SET(xpd->digital_inputs, pos)) {
+ DBG("Ignoring signal sent to digital input line\n");
+ return 0;
+ }
+ switch(txsig) {
+ case ZT_TXSIG_ONHOOK:
+ xpd->ringing[pos] = 0;
+ BIT_CLR(xpd->cid_on, pos);
+ 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);
+ return ret;
+ }
+ ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off
+#if 0
+ switch(chan->sig) {
+ case ZT_SIG_EM:
+ case ZT_SIG_FXOKS:
+ case ZT_SIG_FXOLS:
+ xpd->lasttxhook[pos] = xpd->idletxhookstate[pos];
+ break;
+ case ZT_SIG_FXOGS:
+ xpd->lasttxhook[pos] = FXS_LINE_TIPOPEN;
+ break;
+ }
+#endif
+ break;
+ case ZT_TXSIG_OFFHOOK:
+ if(xpd->ringing[pos]) {
+ BIT_SET(xpd->cid_on, pos);
+ ret = CALL_XMETHOD(CHAN_CID, xpd->xbus, xpd, pos); // CALLER ID
+ }
+ xpd->ringing[pos] = 0;
+#if 0
+ switch(chan->sig) {
+ case ZT_SIG_EM:
+ xpd->lasttxhook[pos] = FXS_LINE_REV_ACTIVE;
+ break;
+ default:
+ xpd->lasttxhook[pos] = xpd->idletxhookstate[pos];
+ break;
+ }
+#endif
+ break;
+ case ZT_TXSIG_START:
+ xpd->lasttxhook[pos] = FXS_LINE_RING;
+ xpd->ringing[pos] = 1;
+ BIT_CLR(xpd->cid_on, pos);
+ if(IS_SET(xpd->digital_outputs, pos)) {
+ DBG("%s/%s/%d: %s digital output ON\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+ ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1);
+ return ret;
+ }
+ ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on
+ break;
+ case ZT_TXSIG_KEWL:
+ xpd->lasttxhook[pos] = FXS_LINE_DISABLED;
+ break;
+ default:
+ NOTICE("%s: Can't set tx state to %s (%d)\n", __FUNCTION__, txsig2str(txsig), txsig);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+#else
int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
{
int ret = 0;
@@ -417,7 +523,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
DBG("%s/%s/%d: fall through ZT_OFFHOOK\n", xbus->busname, xpd->xpdname, pos);
// Fall through
case ZT_OFFHOOK:
- DBG("%s/%s/%d: ignoring (PHONE)\n", xbus->busname, xpd->xpdname, pos);
+ DBG("%s/%s/%d: ZT_OFFHOOK (ignoring for PHONES)\n", xbus->busname, xpd->xpdname, pos);
break;
case ZT_WINK:
WARN("No code yet\n");
@@ -426,7 +532,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
WARN("No code yet\n");
break;
case ZT_RING:
- DBG("%s/%s/%d: ringing[%d]=%d\n", xbus->busname, xpd->xpdname, pos, pos, xpd->ringing[pos]);
+ 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;
@@ -448,6 +554,7 @@ int FXS_card_sethook(xbus_t *xbus, xpd_t *xpd, int pos, int hookstate)
}
return ret;
}
+#endif
/*
* INPUT polling is done via SLIC register 0x06 (same as LEDS):
@@ -463,6 +570,7 @@ static void poll_inputs(xbus_t *xbus, xpd_t *xpd)
{
int i;
+ BUG_ON(xpd->id != 0); // Only unit #0 has digital inputs
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
int pos = input_channels[i];
@@ -478,9 +586,13 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- if((rate_limit++ % 1000) == 0) {
- poll_inputs(xbus, xpd);
+#if POLL_DIGITAL_INPUTS
+ if(poll_digital_inputs && xpd->id == 0) {
+ if((rate_limit++ % 1000) == 0) {
+ poll_inputs(xbus, xpd);
+ }
}
+#endif
handle_fxs_leds(xpd);
return 0;
}
@@ -499,11 +611,14 @@ static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on)
BUG_ON(!xbus);
BUG_ON(!xpd);
- lines &= xpd->enabled_chans; // Ignore disabled channels
if(!lines) {
return 0;
}
DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
+ // Make sure we use normal (low battery) power
+ for_each_line(xpd, i)
+ if (BIT_SET(lines,i))
+ do_chan_power(xbus, xpd, BIT(i), 0);
XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
len = slic_cmd_direct_write(sc, lines, 0x40, value);
@@ -522,20 +637,21 @@ static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on)
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, xpp_line_t lines)
+static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, int pos)
{
int ret = 0;
xpacket_t *pack;
slic_cmd_t *sc;
int i;
+ xpp_line_t lines = BIT(pos);
BUG_ON(!xbus);
BUG_ON(!xpd);
- lines &= xpd->enabled_chans; // Ignore disabled channels
if(!lines) {
return 0;
}
- DBG("Channel CID: 0x%04X\n", lines);
+ DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos);
+ //do_chan_power(xbus, xpd, BIT(pos), 0); // Low battery for normal (non-ring) operation
XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
pack->datalen = slic_cmd_direct_write(sc, lines, 0x40, FXS_LINE_CID);
@@ -552,14 +668,13 @@ static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on)
struct FXS_priv_data *priv;
xpacket_t *pack;
slic_cmd_t *sc;
- xpp_line_t mask = (1 << pos);
+ xpp_line_t mask = BIT(pos);
int len;
enum fxs_state value = (on) ? 0x04 : 0x01;
BUG_ON(!xbus);
BUG_ON(!xpd);
priv = xpd->priv;
- mask &= xpd->enabled_chans; // Ignore disabled channels
if(!mask) {
return 0;
}
@@ -573,10 +688,10 @@ static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on)
packet_send(xbus, pack);
if(on) {
- DO_BLINK(priv,pos,LED_GREEN,LED_BLINK);
+ MARK_BLINK(priv,pos,LED_GREEN,LED_BLINK);
} else {
if(IS_BLINKING(priv, pos, LED_GREEN))
- DO_BLINK(priv,pos,LED_GREEN,0);
+ MARK_BLINK(priv,pos,LED_GREEN,0);
}
return ret;
}
@@ -617,33 +732,6 @@ static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, SLIC_INIT)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_data_t *slic;
- struct slic_init_data *source;
- int i;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- DBG("INITIALIZING SLIC\n");
- for(i = 0; i < ARRAY_SIZE(slic_init_data); i++) {
- source = &slic_init_data[i];
- XPACKET_NEW(pack, xbus, FXS, SLIC_INIT, xpd->id);
- RPACKET_FIELD(pack, FXS, SLIC_INIT, lines) = source->lines;
-
- slic = &RPACKET_FIELD(pack, FXS, SLIC_INIT, slic_data);
- slic->len = source->slic_data.len;
- memcpy(slic->data, source->slic_data.data, source->slic_data.len);
- pack->datalen = sizeof(xpp_line_t) + slic->len + 1;
-// dump_packet("SLIC", pack, print_dbg);
- packet_send(xbus, pack);
- mdelay(1); // FIXME: check with Dima
- }
- return ret;
-}
-
static /* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
{
int ret = 0;
@@ -683,7 +771,7 @@ HANDLER_DEF(FXS, SIG_CHANGED)
}
#if 0
Is this needed?
- for_each_enabled_line(xpd, i) {
+ for_each_line(xpd, i) {
if(IS_SET(sig_toggles, i))
do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!)
}
@@ -695,15 +783,15 @@ HANDLER_DEF(FXS, SIG_CHANGED)
struct zt_chan *chan = &xpd->span.chans[i];
xpd->ringing[i] = 0; // No more ringing...
- DO_BLINK(priv,i,LED_GREEN,0);
+ MARK_BLINK(priv,i,LED_GREEN,0);
if(IS_SET(sig_status, i)) {
DBG("OFFHOOK: channo=%d\n", chan->channo);
- DO_LED(priv,i,LED_GREEN,LED_ON);
+ MARK_LED(priv,i,LED_GREEN,LED_ON);
BIT_SET(xpd->hookstate, i);
zt_hooksig(chan, ZT_RXSIG_OFFHOOK);
} else {
DBG("ONHOOK channo=%d\n", chan->channo);
- DO_LED(priv,i,LED_GREEN,LED_OFF);
+ MARK_LED(priv,i,LED_GREEN,LED_OFF);
BIT_CLR(xpd->hookstate, i);
zt_hooksig(chan, ZT_RXSIG_ONHOOK);
}
@@ -770,7 +858,6 @@ HANDLER_DEF(FXS, SLIC_REPLY)
return 0;
}
-
xproto_table_t PROTO_TABLE(FXS) = {
.owner = THIS_MODULE,
.entries = {
@@ -784,8 +871,13 @@ xproto_table_t PROTO_TABLE(FXS) = {
.card_new = FXS_card_new,
.card_init = FXS_card_init,
.card_remove = FXS_card_remove,
- .card_zaptel_registration = FXS_card_zaptel_registration,
+ .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),
@@ -826,7 +918,8 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
int i;
int led;
- BUG_ON(!xpd);
+ if(!xpd)
+ return -ENODEV;
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
@@ -984,9 +1077,8 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
len = parse_slic_cmd(p, &sc, &priv->requested_reply);
if(len < 0)
return len;
- sc.lines &= xpd->enabled_chans; // Ignore disabled channels
if(!sc.lines) {
- NOTICE("%s: no enabled channels are marked. Skip.\n", __FUNCTION__);
+ NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
return 0;
}
dump_slic_cmd("WRITE_SLIC", &sc);
@@ -1006,7 +1098,8 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
int i;
int ret;
- BUG_ON(!xpd);
+ if(!xpd)
+ return -ENODEV;
for(i = 0; i < count; /* noop */) {
for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
if(i >= count)
@@ -1032,6 +1125,12 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
int __init card_fxs_startup(void)
{
INFO("%s revision %s\n", THIS_MODULE->name, ZAPTEL_VERSION);
+#ifdef POLL_DIGITAL_INPUTS
+ INFO("FEATURE: %s with DIGITAL INPUTS support (%s activated)\n",
+ THIS_MODULE->name, (poll_digital_inputs) ? "is" : "is not");
+#else
+ INFO("FEATURE: %s without DIGITAL INPUTS support\n", THIS_MODULE->name);
+#endif
xproto_register(&PROTO_TABLE(FXS));
return 0;
}