summaryrefslogtreecommitdiff
path: root/xivovp/base.c
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2010-12-30 18:38:06 +0100
committerNoe Rubinstein <nrubinstein@proformatique.com>2010-12-30 18:38:06 +0100
commitcee91eb231da1af9298a103e93b11ead669f35cb (patch)
tree9eaabaf3c663bbfa9d643787bf7d8a5b51f40776 /xivovp/base.c
parent0f99ebd48f28d1b92e053421410d1c81d9fb4da1 (diff)
polarization, cosmetization
Diffstat (limited to 'xivovp/base.c')
-rw-r--r--xivovp/base.c145
1 files changed, 78 insertions, 67 deletions
diff --git a/xivovp/base.c b/xivovp/base.c
index 8518c5e..afe2084 100644
--- a/xivovp/base.c
+++ b/xivovp/base.c
@@ -25,14 +25,38 @@
#define TRACES_VANISH_DEFAULT 2000
+#define NB_LINES 2
+#define TICK_JIFFIES(n) DIV_ROUND_UP(n * HZ, 1000)
+#define VP_TICK_JIFFIES TICK_JIFFIES(VP_TICK_MS)
+
+#define DEBUG_SELECT_RUNNING (VP_DBG_ERROR | VP_DBG_WARNING | VP_DBG_INFO)
+
+#define FXS_TIMESLOT 1
+#define FXO_TIMESLOT 3
+
+#ifdef AUDIO
+#define TS_MASK ((1u << FXS_TIMESLOT) | (1u << FXO_TIMESLOT))
+#endif
+
+#define REVERSE_POLARITY(line) (!( \
+ (!reverse_polarity) ^ \
+ (!(line)->reverse_polarity) ^ \
+ (!(line)->message_waiting)))
+
+#define POL(line, sig) (REVERSE_POLARITY(line) ? sig ## _POLREV : sig)
+
static uint init_dbg = VP_DBG_ALL;
static int traces_vanish = TRACES_VANISH_DEFAULT;
static int alawoverride = 1; /* It's named like that in every DAHDI driver
except I prefer it to be 1 so the name
doesn't make much sense. */
+static int reverse_polarity = false;
+
module_param(init_dbg, uint, 0444);
module_param(traces_vanish, int, 0444);
module_param(alawoverride, int, 0600);
+module_param(reverse_polarity, int, 0600);
+
MODULE_PARM_DESC(init_dbg,
"initial VP_API debug mask (default: " __stringify(VP_DBG_ALL) ")");
MODULE_PARM_DESC(traces_vanish,
@@ -41,39 +65,25 @@ MODULE_PARM_DESC(traces_vanish,
"to only ERROR/WARNING/INFO (default: "
__stringify(TRACES_VANISH_DEFAULT) ")");
-#define NB_LINES 2
-#define TICK_JIFFIES(n) DIV_ROUND_UP(n * HZ, 1000)
-#define VP_TICK_JIFFIES TICK_JIFFIES(VP_TICK_MS)
-
-#define DEBUG_SELECT_RUNNING (VP_DBG_ERROR \
- | VP_DBG_WARNING \
- | VP_DBG_INFO)
-
-
-#define FXS_TIMESLOT (1)
-#define FXO_TIMESLOT (3)
-
-#ifdef AUDIO
-#define TS_MASK ((1u << FXS_TIMESLOT) | (1u << FXO_TIMESLOT))
-#endif
-
enum xivovp_line_type { FXS_LINE = 0, FXO_LINE = 1 };
struct xivovp_line {
enum xivovp_line_type type;
- int ready;
+ bool ready;
Vp890LineObjectType line_obj;
VpLineCtxType vp_ctx;
struct dahdi_chan chan;
- int txsig_pending;
+ bool txsig_pending;
enum dahdi_txsig txsig;
spinlock_t lock;
- //int reverse_polarity;
+ bool reverse_polarity;
+ bool message_waiting;
+ bool previous_polarity;
};
static struct xivovp {
@@ -135,11 +145,19 @@ static int xivovp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
spin_lock_irqsave(&line->lock, flags);
line->txsig = txsig;
- line->txsig_pending = 1;
+ line->txsig_pending = true;
spin_unlock_irqrestore(&line->lock, flags);
return 0;
}
+#define HOOKSIG_TRACE(line, txsig, vpsig) \
+ printk(KERN_DEBUG DRV_NAME "(chan %d): " \
+ "transmitting %s on %s, setting to %s%s.\n", \
+ chanpos, txsig, \
+ (line->type == FXO_LINE ? "FXO" : "FXS"), vpsig, \
+ (REVERSE_POLARITY(line) && line->type == FXS_LINE ? \
+ "_POLREV" : ""));
+
/*
* hooksig transmits sig from DAHDI to VP.
* sig from VP is handled in vp_tick and transmitted to DAHDI with
@@ -152,53 +170,42 @@ static void xivovp_hooksig_pvt(struct xivovp_line* line, enum dahdi_txsig txsig)
switch (txsig) {
case DAHDI_TXSIG_START:
case DAHDI_TXSIG_OFFHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
- "transmitting %s state on FXO, "
- "setting to TALK.\n",
- chanpos, txsig == DAHDI_TXSIG_START ?
- "START" :
- "OFFHOOK");
+ HOOKSIG_TRACE(line, (txsig == DAHDI_TXSIG_START ?
+ "START" : "OFFHOOK"), "TALK");
VpSetLineState(&line->vp_ctx, VP_LINE_FXO_TALK);
break;
case DAHDI_TXSIG_ONHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
- "transmitting ONHOOK on FXO, "
- "setting to OHT.\n", chanpos);
+ HOOKSIG_TRACE(line, "ONHOOK", "TALK");
VpSetLineState(&line->vp_ctx, VP_LINE_FXO_OHT);
break;
default:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
+ printk(KERN_DEBUG DRV_NAME "(chan %d): "
"unsupported tx state for FXO: %d\n",
chanpos, txsig);
}
} else /* FXS */ {
switch (txsig) {
case DAHDI_TXSIG_START:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
- "transmitting START on FXS, "
- "setting to RINGING.\n", chanpos);
- VpSetLineState(&line->vp_ctx, VP_LINE_RINGING);
+ HOOKSIG_TRACE(line, "START", "RINGING");
+ VpSetLineState(&line->vp_ctx,
+ POL(line, VP_LINE_RINGING));
break;
case DAHDI_TXSIG_OFFHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
- "transmitting OFFHOOK on FXS, "
- "setting to TALK.\n", chanpos);
- VpSetLineState(&line->vp_ctx, VP_LINE_TALK);
+ HOOKSIG_TRACE(line, "OFFHOOK", "TALK");
+ VpSetLineState(&line->vp_ctx, POL(line, VP_LINE_TALK));
break;
case DAHDI_TXSIG_ONHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
- "transmitting ONHOOK on FXS, "
- "setting to OHT.\n", chanpos);
- VpSetLineState(&line->vp_ctx, VP_LINE_OHT);
+ HOOKSIG_TRACE(line, "ONHOOK", "OHT");
+ VpSetLineState(&line->vp_ctx, POL(line, VP_LINE_OHT));
break;
case DAHDI_TXSIG_KEWL:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
+ printk(KERN_DEBUG DRV_NAME "(chan %d): "
"transmitting remote disconnect (KEWL)"
"on FXS\n", chanpos);
VpSetLineState(&line->vp_ctx, VP_LINE_DISCONNECT);
break;
default:
- printk(KERN_WARNING DRV_NAME "(chan %d): "
+ printk(KERN_DEBUG DRV_NAME "(chan %d): "
"unsupported tx state for FXS: %d\n",
chanpos, txsig);
}
@@ -210,13 +217,23 @@ static void xivovp_handle_txsig(void)
static int said;
int i;
enum dahdi_txsig txsig;
+ struct xivovp_line *line;
unsigned long flags;
+ bool pol_change;
for (i = 0; i < NB_LINES; i++) {
- if (xivovp.line[i].ready && xivovp.line[i].txsig_pending) {
+ line = &xivovp.line[i];
+ pol_change = line->type == FXS_LINE &&
+ line->previous_polarity != REVERSE_POLARITY(line);
+ //XXX shouldn't do that while line is ringing?
+
+ if (line->ready && (line->txsig_pending || pol_change)) {
spin_lock_irqsave(&xivovp.line[i].lock, flags);
+
txsig = xivovp.line[i].txsig;
- xivovp.line[i].txsig_pending = 0;
+ xivovp.line[i].txsig_pending = false;
+ line->previous_polarity = REVERSE_POLARITY(line);
+
spin_unlock_irqrestore(&xivovp.line[i].lock, flags);
xivovp_hooksig_pvt(&xivovp.line[i], txsig);
@@ -254,8 +271,8 @@ static void vp_post_init(VpEventType *event)
printk(KERN_INFO DRV_NAME ": vp dev init complete\n");
- vpst = VpSetOption(NULL, event->pDevCtx,
- VP_OPTION_ID_EVENT_MASK, &event_mask);
+ vpst = VpSetOption(NULL, event->pDevCtx, VP_OPTION_ID_EVENT_MASK,
+ &event_mask);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": "
"VpSetOption VP_OPTION_ID_EVENT_MASK "
@@ -264,47 +281,41 @@ static void vp_post_init(VpEventType *event)
/* FXS */
vpst = VpSetOption(&xivovp.line[FXS_LINE].vp_ctx, NULL,
- VP_OPTION_ID_TIMESLOT,
- &fxs_timeslot);
+ VP_OPTION_ID_TIMESLOT, &fxs_timeslot);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": "
"VpSetOption FXS VP_OPTION_ID_TIMESLOT "
"returned %d\n", (int)vpst);
}
- vpst = VpSetLineState(&xivovp.line[FXS_LINE].vp_ctx,
- VP_LINE_OHT);
+ vpst = VpSetLineState(&xivovp.line[FXS_LINE].vp_ctx, VP_LINE_OHT);
if (vpst != VP_STATUS_SUCCESS) {
- printk(KERN_ERR DRV_NAME ": "
- "VpSetLineState returned %d\n", (int)vpst);
+ printk(KERN_ERR DRV_NAME ": VpSetLineState returned %d\n",
+ (int)vpst);
}
vpst = VpCalLine(&xivovp.line[FXS_LINE].vp_ctx);
if (vpst != VP_STATUS_SUCCESS) {
- printk(KERN_ERR DRV_NAME ": "
- "VpCalLine returned %d\n", (int)vpst);
+ printk(KERN_ERR DRV_NAME ": VpCalLine returned %d\n",
+ (int)vpst);
}
/* FXO */
- vpst = VpSetOption(&xivovp.line[FXO_LINE].vp_ctx, NULL,
- VP_OPTION_ID_TIMESLOT,
- &fxo_timeslot);
+ vpst = VpSetOption(&xivovp.line[FXO_LINE].vp_ctx, NULL,
+ VP_OPTION_ID_TIMESLOT, &fxo_timeslot);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": "
"VpSetOption FXO VP_OPTION_ID_TIMESLOT "
"returned %d\n", (int)vpst);
}
- vpst = VpSetLineState(&xivovp.line[FXO_LINE].vp_ctx,
- VP_LINE_FXO_OHT);
+ vpst = VpSetLineState(&xivovp.line[FXO_LINE].vp_ctx, VP_LINE_FXO_OHT);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": "
"VpSetLineState returned %d\n", (int)vpst);
}
- xivovp.line[FXO_LINE].ready = 1; /* No VpCalLine for FXO */
-
- // XXX What happens if lines aren't connected?
+ xivovp.line[FXO_LINE].ready = true; /* No VpCalLine for FXO */
count_and_stop_traces = TRUE;
}
@@ -312,7 +323,7 @@ static void vp_post_init(VpEventType *event)
static void event_calibration_complete(VpEventType *event)
{
printk(KERN_INFO DRV_NAME ": calibration succeeded\n");
- xivovp_line_from_ctx(event->pLineCtx)->ready = 1;
+ xivovp_line_from_ctx(event->pLineCtx)->ready = true;
vp_set_debug_select_running();
}
@@ -385,8 +396,7 @@ static void event_ring_on(VpEventType *event)
static void event_ring_off(VpEventType *event)
{
struct xivovp_line *line = xivovp_line_from_ctx(event->pLineCtx);
- printk(KERN_INFO DRV_NAME ": "
- "received ring off event on %s\n",
+ printk(KERN_INFO DRV_NAME ": received ring off event on %s\n",
line->chan.name);
dahdi_hooksig(&line->chan, DAHDI_RXSIG_ONHOOK);
}
@@ -396,6 +406,7 @@ static void event_polarity_reversal(VpEventType *event)
struct xivovp_line *line = xivovp_line_from_ctx(event->pLineCtx);
printk(KERN_INFO DRV_NAME ": received polarity reversal event on %s\n",
line->chan.name);
+ line->reverse_polarity = !line->reverse_polarity;
dahdi_qevent_lock(&line->chan, DAHDI_EVENT_POLARITY);
}