summaryrefslogtreecommitdiff
path: root/xpp/card_fxo.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_fxo.c')
-rw-r--r--xpp/card_fxo.c120
1 files changed, 60 insertions, 60 deletions
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index bc67950..e568885 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -156,7 +156,7 @@ static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on)
BIT_CLR(priv->ledstate[which], chan);
}
}
- DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off");
+ LINE_DBG(xpd, chan, "LED: which=%d -- %s\n", which, (on) ? "on" : "off");
ret = DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x20, on);
out:
return ret;
@@ -184,8 +184,7 @@ static void handle_fxo_leds(xpd_t *xpd)
mod_value = DEFAULT_LED_PERIOD; /* safety value */
// led state is toggled
if((timer_count % mod_value) == 0) {
- DBG("%s/%s/%d: ledstate=%s\n", xpd->xbus->busname, xpd->xpdname, i,
- (IS_SET(priv->ledstate[color], i))?"ON":"OFF");
+ LINE_DBG(xpd, i, "ledstate=%s\n", (IS_SET(priv->ledstate[color], i))?"ON":"OFF");
if(!IS_SET(priv->ledstate[color], i)) {
do_led(xpd, i, color, 1);
} else {
@@ -213,7 +212,7 @@ void update_zap_ring(xpd_t *xpd, int pos, bool on)
BIT_SET(xpd->cid_on, pos);
rxsig = ZT_RXSIG_OFFHOOK;
}
- pcm_recompute(xpd);
+ pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
/*
* We should not spinlock before calling zt_hooksig() as
* it may call back into our xpp_hooksig() and cause
@@ -231,13 +230,13 @@ static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_zap)
BUG_ON(!priv);
atomic_set(&priv->ring_debounce[pos], 0); /* Stop debouncing */
if(on && !xpd->ringing[pos]) {
- DBG("%s/%s/%d: START\n", xpd->xbus->busname, xpd->xpdname, pos);
+ LINE_DBG(xpd, pos, "START\n");
xpd->ringing[pos] = 1;
MARK_BLINK(priv, pos, LED_GREEN, LED_BLINK_RING);
if(update_zap)
update_zap_ring(xpd, pos, on);
} else if(!on && xpd->ringing[pos]) {
- DBG("%s/%s/%d: STOP\n", xpd->xbus->busname, xpd->xpdname, pos);
+ LINE_DBG(xpd, pos, "STOP\n");
xpd->ringing[pos] = 0;
if(IS_BLINKING(priv, pos, LED_GREEN))
MARK_BLINK(priv, pos, LED_GREEN, 0);
@@ -260,12 +259,12 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
priv = xpd->priv;
BUG_ON(!priv);
if(!IS_SET(priv->battery, pos)) {
- DBG("%s/%s/%d: WARNING: called while battery is off\n", xbus->busname, xpd->xpdname, pos);
+ LINE_DBG(xpd, pos, "WARNING: called while battery is off\n");
}
spin_lock_irqsave(&xpd->lock, flags);
mark_ring(xpd, pos, 0, 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");
+ LINE_DBG(xpd, pos, "SETHOOK: value=0x%02X %s\n", value, (to_offhook)?"OFFHOOK":"ONHOOK");
if(to_offhook)
MARK_ON(priv, pos, LED_GREEN);
else
@@ -289,11 +288,15 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
/*---------------- FXO: Methods -------------------------------------------*/
-static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte revision)
+static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, byte revision)
{
xpd_t *xpd = NULL;
- int channels = min(8, CHANNELS_PERXPD);
+ int channels;
+ if(subtype == 2)
+ channels = min(2, CHANNELS_PERXPD);
+ else
+ channels = min(8, CHANNELS_PERXPD);
xpd = xpd_alloc(sizeof(struct FXO_priv_data), proto_table, channels);
if(!xpd)
return NULL;
@@ -309,23 +312,23 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
- DBG("%s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "\n");
#ifdef CONFIG_PROC_FS
if(priv->regfile) {
- DBG("Removing xpd DAA file %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Removing xpd DAA file\n");
remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
priv->regfile->data = NULL;
}
#ifdef WITH_METERING
if(priv->meteringfile) {
- DBG("Removing xpd metering tone file %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Removing xpd metering tone file\n");
priv->meteringfile->data = NULL;
remove_proc_entry(PROC_METERING_FNAME, xpd->proc_xpd_dir);
priv->meteringfile = NULL;
}
#endif
if(priv->fxo_info) {
- DBG("Removing xpd FXO_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Removing xpd FXO_INFO file\n");
remove_proc_entry(PROC_FXO_INFO_FNAME, xpd->proc_xpd_dir);
priv->fxo_info = NULL;
}
@@ -341,29 +344,29 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
#ifdef CONFIG_PROC_FS
- DBG("Creating FXO_INFO file for %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Creating FXO_INFO file\n");
priv->fxo_info = create_proc_read_entry(PROC_FXO_INFO_FNAME, 0444, xpd->proc_xpd_dir, proc_fxo_info_read, xpd);
if(!priv->fxo_info) {
- ERR("Failed to create proc '%s' for %s/%s\n", PROC_FXO_INFO_FNAME, xbus->busname, xpd->xpdname);
+ XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_FXO_INFO_FNAME);
ret = -ENOENT;
goto err;
}
priv->fxo_info->owner = THIS_MODULE;
#ifdef WITH_METERING
- DBG("Creating Metering tone file for %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Creating Metering tone file\n");
priv->meteringfile = create_proc_read_entry(PROC_METERING_FNAME, 0444, xpd->proc_xpd_dir,
proc_xpd_metering_read, xpd);
if(!priv->meteringfile) {
- ERR("%s/%s: Failed to create proc file for metering tone\n", xbus->busname, xpd->xpdname);
+ XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_METERING_FNAME);
ret = -ENOENT;
goto err;
}
priv->meteringfile->owner = THIS_MODULE;
#endif
- DBG("Creating DAAs file for %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "Creating DAAs file\n");
priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
if(!priv->regfile) {
- ERR("Failed to create proc file for DAAs of %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_REGISTER_FNAME);
ret = -ENOENT;
goto err;
}
@@ -379,7 +382,7 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
for_each_line(xpd, i) {
do_sethook(xpd, i, 0);
}
- DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "done\n");
for_each_line(xpd, i) {
do_led(xpd, i, LED_GREEN, 0);
}
@@ -391,11 +394,11 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
do_led(xpd, i, LED_GREEN, 0);
msleep(50);
}
- pcm_recompute(xpd);
+ pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
return 0;
err:
clean_proc(xbus, xpd);
- ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
+ XPD_ERR(xpd, "Failed initializing registers (%d)\n", ret);
return ret;
}
@@ -405,7 +408,7 @@ static int FXO_card_remove(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
- DBG("%s/%s\n", xbus->busname, xpd->xpdname);
+ XPD_DBG(xpd, "\n");
clean_proc(xbus, xpd);
return 0;
}
@@ -421,11 +424,11 @@ static int FXO_card_zaptel_preregistration(xpd_t *xpd, bool on)
BUG_ON(!xbus);
priv = xpd->priv;
BUG_ON(!priv);
- DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
+ XPD_DBG(xpd, "%s\n", (on)?"ON":"OFF");
for_each_line(xpd, i) {
struct zt_chan *cur_chan = &xpd->chans[i];
- DBG("setting FXO channel %d\n", i);
+ XPD_DBG(xpd, "setting FXO channel %d\n", i);
snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXO/%02d/%1d%1d/%d",
xbus->num, xpd->addr.unit, xpd->addr.subunit, i);
cur_chan->chanpos = i + 1;
@@ -450,7 +453,7 @@ static int FXO_card_zaptel_postregistration(xpd_t *xpd, bool on)
BUG_ON(!xbus);
priv = xpd->priv;
BUG_ON(!priv);
- DBG("%s/%s (%d)\n", xbus->busname, xpd->xpdname, on);
+ XPD_DBG(xpd, "%s\n", (on)?"ON":"OFF");
for_each_line(xpd, i) {
MARK_OFF(priv, i, LED_GREEN);
msleep(2);
@@ -466,7 +469,7 @@ int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
priv = xpd->priv;
BUG_ON(!priv);
- DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+ LINE_DBG(xpd, pos, "%s\n", txsig2str(txsig));
BUG_ON(xpd->direction != TO_PSTN);
/* XXX Enable hooksig for FXO XXX */
switch(txsig) {
@@ -479,10 +482,11 @@ int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
do_sethook(xpd, pos, 0);
break;
default:
- NOTICE("Can't set tx state to %s (%d)\n", txsig2str(txsig), txsig);
+ XPD_NOTICE(xpd, "Can't set tx state to %s (%d)\n",
+ txsig2str(txsig), txsig);
return -EINVAL;
}
- pcm_recompute(xpd);
+ pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
return 0;
}
@@ -591,26 +595,26 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
BUG_ON(!xpd);
switch (cmd) {
case WCTDM_SET_ECHOTUNE:
- DBG("-- Setting echo registers: \n");
+ XPD_DBG(xpd, "-- Setting echo registers: \n");
/* first off: check if this span is fxs. If not: -EINVALID */
if (copy_from_user(&echotune_data, (void __user *)arg, sizeof(echotune_data)))
return -EFAULT;
for (i = 0; i < ARRAY_SIZE(echotune_regs); i++) {
- DBG("Reg=0x%02X, data=0x%02X\n", echotune_regs[i], echotune_data[i]);
+ XPD_DBG(xpd, "Reg=0x%02X, data=0x%02X\n", echotune_regs[i], echotune_data[i]);
ret = DAA_DIRECT_REQUEST(xpd->xbus, xpd, pos, DAA_WRITE, echotune_regs[i], echotune_data[i]);
if (ret < 0) {
- NOTICE("%s/%s/%d: Couldn't write %0x02X to register %0x02X\n",
- xpd->xbus->busname, xpd->xpdname, pos, echotune_data[i], echotune_regs[i]);
+ LINE_NOTICE(xpd, pos, "Couldn't write %0x02X to register %0x02X\n",
+ echotune_data[i], echotune_regs[i]);
return ret;
}
msleep(1);
}
- DBG("-- Set echo registers successfully\n");
+ XPD_DBG(xpd, "-- Set echo registers successfully\n");
break;
default:
- DBG("%s/%s/%d: Unknown command 0x%X.\n", xpd->xbus->busname, xpd->xpdname, pos, cmd);
+ LINE_DBG(xpd, pos, "Unknown command 0x%X.\n", cmd);
return -ENOTTY;
}
return 0;
@@ -631,8 +635,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
}
XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
#if 0
- DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
- xbus->busname, xpd->xpdname, chipsel,
+ LINE_DBG(xpd, chisel, "%c%c R%02X S%02X %02X %02X\n",
(writing)?'W':'R',
(do_subreg)?'S':'D',
regnum, subreg, data_low, data_high);
@@ -659,7 +662,7 @@ static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
+ XPD_DBG(xpd, "%s\n", (on) ? "on" : "off");
return ret;
}
@@ -667,7 +670,7 @@ static /* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on)
{
BUG_ON(!xbus);
BUG_ON(!xpd);
- DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off");
+ LINE_DBG(xpd, chan, "%s\n", (on) ? "on" : "off");
return DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x40, (on)?0x04:0x01);
}
@@ -692,22 +695,21 @@ HANDLER_DEF(FXO, SIG_CHANGED)
}
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);
+ XPD_DBG(xpd, "(PSTN) sig_toggles=0x%04X sig_status=0x%04X\n", sig_toggles, sig_status);
spin_lock_irqsave(&xpd->lock, flags);
for_each_line(xpd, i) {
int debounce;
if(IS_SET(sig_toggles, i)) {
if(!IS_SET(priv->battery, i)) {
- DBG("%s/%s/%d: SIG_CHANGED while battery is off.\n",
- xbus->busname, xpd->xpdname, i);
+ LINE_DBG(xpd, i, "SIG_CHANGED while battery is off.\n");
// FIXME: allow dialing without battery polling...
// continue;
}
/* First report false ring alarms */
debounce = atomic_read(&priv->ring_debounce[i]);
if(debounce)
- NOTICE("%s/%s/%d: debounced %d ticks\n", xbus->busname, xpd->xpdname, i, debounce);
+ LINE_NOTICE(xpd, i, "debounced %d ticks\n", debounce);
/*
* Now set a new ring alarm.
* It will be checked in handle_fxo_ring()
@@ -733,7 +735,7 @@ static void update_battery_status(xpd_t *xpd, byte data_low, lineno_t chipsel)
* Check for battery voltage fluctuations
*/
if(IS_SET(priv->battery, chipsel) && priv->battery_debounce[chipsel]++ > BAT_DEBOUNCE) {
- DBG("%s/%s/%d: BATTERY OFF voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ LINE_DBG(xpd, chipsel, "BATTERY OFF voltage=%d\n", bat);
BIT_CLR(priv->battery, chipsel);
if(SPAN_REGISTERED(xpd))
zt_qevent_lock(&xpd->chans[chipsel], ZT_EVENT_ALARM);
@@ -742,7 +744,7 @@ static void update_battery_status(xpd_t *xpd, byte data_low, lineno_t chipsel)
} else {
priv->battery_debounce[chipsel] = 0;
if(!IS_SET(priv->battery, chipsel)) {
- DBG("%s/%s/%d: BATTERY ON voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ LINE_DBG(xpd, chipsel, "BATTERY ON voltage=%d\n", bat);
BIT_SET(priv->battery, chipsel);
if(SPAN_REGISTERED(xpd))
zt_qevent_lock(&xpd->chans[chipsel], ZT_EVENT_NOALARM);
@@ -768,7 +770,7 @@ static void update_battery_status(xpd_t *xpd, byte data_low, lineno_t chipsel)
BIT_CLR(priv->polarity, chipsel);
priv->polarity_counter[chipsel] = 0;
/* Inform Zaptel */
- DBG("%s/%s/%d: Send ZT_EVENT_POLARITY\n", xpd->xbus->busname, xpd->xpdname, chipsel);
+ LINE_DBG(xpd, chipsel, "Send ZT_EVENT_POLARITY\n");
zt_qevent_lock(&xpd->chans[chipsel], ZT_EVENT_POLARITY);
#if 0
/*
@@ -780,7 +782,7 @@ static void update_battery_status(xpd_t *xpd, byte data_low, lineno_t chipsel)
*/
do_sethook(xpd, chipsel, 0);
update_line_status(xpd, chipsel, 0);
- pcm_recompute(xpd);
+ pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
#endif
}
}
@@ -797,11 +799,11 @@ static void update_power_denial(xpd_t *xpd, byte data_low, lineno_t chipsel)
/* Current dropped */
priv->current_counter[chipsel]++;
if (priv->current_counter[chipsel] * poll_battery_interval >= POWER_DENIAL_TIME) {
- DBG("%s/%s/%d: Power Denial Hangup\n", xpd->xbus->busname, xpd->xpdname, chipsel);
+ LINE_DBG(xpd, chipsel, "Power Denial Hangup\n");
priv->current_counter[chipsel] = 0;
do_sethook(xpd, chipsel, 0);
update_line_status(xpd, chipsel, 0);
- pcm_recompute(xpd);
+ pcm_recompute(xpd, xpd->offhook | xpd->cid_on);
}
} else
priv->current_counter[chipsel] = 0;
@@ -819,8 +821,7 @@ static void update_metering_state(xpd_t *xpd, byte data_low, lineno_t chipsel)
priv = xpd->priv;
BUG_ON(!priv);
old_metering_tone = IS_SET(priv->metering_tone_state, chipsel);
- DBG("%s/%s/%d: METERING: %s [dL=0x%X] (%d)\n",
- xpd->xbus->busname, xpd->xpdname, chipsel,
+ LINE_DBG(xpd, chipsel, "METERING: %s [dL=0x%X] (%d)\n",
(metering_tone) ? "ON" : "OFF",
data_low, priv->metering_count[chipsel]);
if(metering_tone && !old_metering_tone) {
@@ -864,8 +865,8 @@ HANDLER_DEF(FXO, DAA_REPLY)
#endif
}
#if 0
- DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
- xpd->xbus_idx, (info->size == 3)?"I":"D",
+ XPD_DBG(xpd, "DAA_REPLY: %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+ (info->size == 3)?"I":"D",
info->reg_num, info->data_low, info->data_high);
#endif
@@ -1073,7 +1074,7 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
BUG_ON(!xpd);
xbus = xpd->xbus;
if(!down_read_trylock(&xbus->in_use)) {
- DBG("Dropped packet. %s is in_use\n", xbus->busname);
+ XBUS_DBG(xbus, "Dropped packet. Is in_use\n");
return -EBUSY;
}
xpd->requested_reply = regcmd;
@@ -1185,15 +1186,14 @@ static int proc_xpd_metering_read(char *page, char **start, off_t off, int count
int __init card_fxo_startup(void)
{
if(ring_debounce <= 0) {
- ERR("%s: ring_debounce=%d. Must be positive number of ticks\n",
- THIS_MODULE->name, ring_debounce);
+ ERR("ring_debounce=%d. Must be positive number of ticks\n", ring_debounce);
return -EINVAL;
}
- INFO("%s revision %s\n", THIS_MODULE->name, XPP_VERSION);
+ INFO("revision %s\n", XPP_VERSION);
#ifdef WITH_METERING
- INFO("FEATURE: %s WITH METERING Detection\n", THIS_MODULE->name);
+ INFO("FEATURE: WITH METERING Detection\n");
#else
- INFO("FEATURE: %s NO METERING Detection\n", THIS_MODULE->name);
+ INFO("FEATURE: NO METERING Detection\n");
#endif
xproto_register(&PROTO_TABLE(FXO));
return 0;