xpp: FXO: in-firmware polarity-reversal detection

PIC_TYPE_2 rev.11039 adds support for polarity reversal detection. Support
those messages.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
This commit is contained in:
Oron Peled 2013-03-14 17:29:15 +02:00 committed by Tzafrir Cohen
parent 104745a775
commit b4ff53c00c
3 changed files with 410 additions and 275 deletions

View File

@ -34,7 +34,10 @@
static const char rcsid[] = "$Id$";
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM(uint, poll_battery_interval, 500, 0644, "Poll battery interval in milliseconds (0 - disable)");
static DEF_PARM(uint, poll_battery_interval, 500, 0644,
"Poll battery interval in milliseconds (0 - disable)");
static DEF_PARM_BOOL(use_polrev_firmware, 1, 0444,
"Use firmware reports of polarity reversal");
#ifdef WITH_METERING
static DEF_PARM(uint, poll_metering_interval, 500, 0644, "Poll metering interval in milliseconds (0 - disable)");
#endif
@ -92,6 +95,7 @@ static int proc_xpd_metering_read(char *page, char **start, off_t off, int count
#endif
#endif
static void dahdi_report_battery(xpd_t *xpd, lineno_t chan);
static void report_polarity_reversal(xpd_t *xpd, xportno_t portno);
#define PROC_REGISTER_FNAME "slics"
#define PROC_FXO_INFO_FNAME "fxo_info"
@ -99,6 +103,10 @@ static void dahdi_report_battery(xpd_t *xpd, lineno_t chan);
#define PROC_METERING_FNAME "metering_read"
#endif
#define REG_INTERRUPT_SRC 0x04 /* 4 - Interrupt Source */
#define REG_INTERRUPT_SRC_POLI BIT(0) /* Polarity Reversal Detect Interrupt*/
#define REG_INTERRUPT_SRC_RING BIT(7) /* Ring Detect Interrupt */
#define REG_DAA_CONTROL1 0x05 /* 5 - DAA Control 1 */
#define REG_DAA_CONTROL1_OH BIT(0) /* Off-Hook. */
#define REG_DAA_CONTROL1_ONHM BIT(3) /* On-Hook Line Monitor */
@ -137,6 +145,9 @@ struct FXO_priv_data {
ushort nobattery_debounce[CHANNELS_PERXPD];
enum polarity_state polarity[CHANNELS_PERXPD];
ushort polarity_debounce[CHANNELS_PERXPD];
int polarity_last_interval[CHANNELS_PERXPD];
#define POLARITY_LAST_INTERVAL_NONE (-1)
#define POLARITY_LAST_INTERVAL_MAX 40
enum power_state power[CHANNELS_PERXPD];
ushort power_denial_delay[CHANNELS_PERXPD];
ushort power_denial_length[CHANNELS_PERXPD];
@ -315,6 +326,7 @@ static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_dahdi)
MARK_BLINK(priv, pos, LED_GREEN, 0);
if(update_dahdi)
update_dahdi_ring(xpd, pos, on);
priv->polarity_last_interval[pos] = POLARITY_LAST_INTERVAL_NONE;
}
}
@ -467,6 +479,7 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
priv->power[i] = POWER_UNKNOWN; /* will be updated on next battery sample */
if(caller_id_style == CID_STYLE_ETSI_DTMF)
oht_pcm(xpd, i, 1);
priv->polarity_last_interval[i] = POLARITY_LAST_INTERVAL_NONE;
}
XPD_DBG(GENERAL, xpd, "done\n");
for_each_line(xpd, i) {
@ -633,7 +646,22 @@ static void handle_fxo_ring(xpd_t *xpd)
priv = xpd->priv;
for_each_line(xpd, i) {
if(atomic_read(&priv->ring_debounce[i]) > 0) {
if (use_polrev_firmware) {
int *t = &priv->polarity_last_interval[i];
if (*t != POLARITY_LAST_INTERVAL_NONE) {
(*t)++;
if (*t > POLARITY_LAST_INTERVAL_MAX) {
LINE_DBG(SIGNAL, xpd, i,
"polrev(GOOD): %d msec\n", *t);
*t = POLARITY_LAST_INTERVAL_NONE;
if (use_polrev_firmware) {
report_polarity_reversal(xpd,
i);
}
}
}
}
if (atomic_read(&priv->ring_debounce[i]) > 0) {
/* Maybe start ring */
if(atomic_dec_and_test(&priv->ring_debounce[i]))
mark_ring(xpd, i, 1, 1);
@ -845,8 +873,8 @@ HANDLER_DEF(FXO, SIG_CHANGED)
for_each_line(xpd, i) {
int debounce;
if(IS_SET(sig_toggles, i)) {
if(priv->battery[i] == BATTERY_OFF) {
if (IS_SET(sig_toggles, i)) {
if (priv->battery[i] == BATTERY_OFF) {
/*
* With poll_battery_interval==0 we cannot have BATTERY_OFF
* so we won't get here
@ -870,6 +898,23 @@ HANDLER_DEF(FXO, SIG_CHANGED)
return 0;
}
static void report_polarity_reversal(xpd_t *xpd, xportno_t portno)
{
/*
* Inform dahdi/Asterisk:
* 1. Maybe used for hangup detection during offhook
* 2. In some countries used to report caller-id
* during onhook but before first ring.
*/
if (caller_id_style == CID_STYLE_ETSI_FSK)
/* will be cleared on ring/offhook */
oht_pcm(xpd, portno, 1);
if (SPAN_REGISTERED(xpd)) {
LINE_DBG(SIGNAL, xpd, portno, "Send DAHDI_EVENT_POLARITY\n");
dahdi_qevent_lock(XPD_CHAN(xpd, portno), DAHDI_EVENT_POLARITY);
}
}
static void update_battery_voltage(xpd_t *xpd, byte data_low, xportno_t portno)
{
struct FXO_priv_data *priv;
@ -961,20 +1006,9 @@ static void update_battery_voltage(xpd_t *xpd, byte data_low, xportno_t portno)
else
BUG();
LINE_DBG(SIGNAL, xpd, portno,
"Polarity changed to %s\n", polname);
/*
* Inform dahdi/Asterisk:
* 1. Maybe used for hangup detection during offhook
* 2. In some countries used to report caller-id during onhook
* but before first ring.
*/
if(caller_id_style == CID_STYLE_ETSI_FSK)
oht_pcm(xpd, portno, 1); /* will be cleared on ring/offhook */
if(SPAN_REGISTERED(xpd)) {
LINE_DBG(SIGNAL, xpd, portno,
"Send DAHDI_EVENT_POLARITY: %s\n", polname);
dahdi_qevent_lock(XPD_CHAN(xpd, portno), DAHDI_EVENT_POLARITY);
}
"Polarity changed to %s\n", polname);
if (!use_polrev_firmware)
report_polarity_reversal(xpd, portno);
}
priv->polarity[portno] = pol;
}
@ -1054,6 +1088,50 @@ static void update_metering_state(xpd_t *xpd, byte data_low, lineno_t portno)
}
#endif
static void got_chip_interrupt(xpd_t *xpd, __u8 data_low,
xportno_t portno)
{
struct FXO_priv_data *priv;
if (!use_polrev_firmware)
return;
priv = xpd->priv;
LINE_DBG(SIGNAL, xpd, portno, "mask=0x%X\n", data_low);
if (!(data_low & REG_INTERRUPT_SRC_POLI))
return;
int t = priv->polarity_last_interval[portno];
if (PHONEDEV(xpd).ringing[portno]) {
priv->polarity_last_interval[portno] =
POLARITY_LAST_INTERVAL_NONE;
LINE_DBG(SIGNAL, xpd, portno,
"polrev(false): %d msec (while ringing)\n", t);
} else if (data_low & REG_INTERRUPT_SRC_RING) {
priv->polarity_last_interval[portno] =
POLARITY_LAST_INTERVAL_NONE;
LINE_DBG(SIGNAL, xpd, portno,
"polrev(false): %d msec (with chip-interrupt ring)\n",
t);
} else if (t == POLARITY_LAST_INTERVAL_NONE) {
priv->polarity_last_interval[portno] = 0;
LINE_DBG(SIGNAL, xpd, portno,
"polrev(start)\n");
} else if (t < POLARITY_LAST_INTERVAL_MAX) {
/*
* Start counting upward from -POLARITY_LAST_INTERVAL_MAX
* Until we reach POLARITY_LAST_INTERVAL_NONE.
* This way we filter bursts of false reports we get
* during ringing
*/
priv->polarity_last_interval[portno] =
POLARITY_LAST_INTERVAL_NONE -
POLARITY_LAST_INTERVAL_MAX;
LINE_DBG(SIGNAL, xpd, portno,
"polrev(false): %d msec (interval shorter than %d)\n",
t, POLARITY_LAST_INTERVAL_MAX);
}
}
static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
{
struct FXO_priv_data *priv;
@ -1063,6 +1141,10 @@ static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
BUG_ON(!priv);
portno = info->portnum;
switch(REG_FIELD(info, regnum)) {
case REG_INTERRUPT_SRC:
got_chip_interrupt(xpd, REG_FIELD(info, data_low),
portno);
break;
case DAA_REG_VBAT:
update_battery_voltage(xpd, REG_FIELD(info, data_low), portno);
break;

View File

@ -1,5 +1,5 @@
#
# $Id: PIC_TYPE_2.hex 9732 2011-08-24 19:13:55Z dima $
# $Id: PIC_TYPE_2.hex 11039 2013-03-07 11:02:16Z dima $
#
:03000000A57A4896
:03000100C41C41DB
@ -96,265 +96,315 @@
:03005C001CCC2099
:03005D00E07180CF
:03005E0002CE705F
:03005F00206743D4
:0300600090AA70F3
:03006100205C021E
:03006200D2018048
:03006300D40E07B1
:0300640003D6437D
:03006500C1CA739A
:03006600022C0366
:03006700C0018055
:03006800024E073E
:0300690021D6435A
:03006A00030A7313
:03006B00901C04E2
:03006C00202180D0
:03006D00030E0778
:03006E00901643A6
:03006F00204A73B1
:03007000030C017D
:03007100901038B4
:03007200210A72EE
:03007300024C1824
:03007400C0303861
:0300750008421925
:03007600603E0FDA
:03007700A7A0221D
:03007800209C00C9
:03007900A7C038E5
:03007A00C00200C1
:03007B00A7CE0706
:03007C00187F02E8
:03007D0014974392
:03007E00643A835E
:03007F00AABC0018
:030080001A7031C2
:03008100C50C1299
:03008200039A904E
:030083007992006F
:03008400A83E078C
:0300850020BF0396
:03008600D007435D
:03008700038A8C5D
:03008800219C00B8
:03008900E07031F3
:03008A00348C189B
:03008B00348A9024
:03008C00348C00B1
:03008D003480318B
:03008E00030C164A
:03008F00206A9054
:0300900034803B7E
:03005F0020074334
:03006000022A7001
:03006100206C020E
:0300620064318086
:03006300A68E075F
:03006400322643FE
:030065002C8A736F
:03006600D00C03B8
:03006700A621804F
:03006800C01E07B0
:0300690014264317
:03006A00743A7372
:03006B00AC5C0486
:03006C0020618090
:03006D0090AE074B
:03006E00205643D6
:03006F00D20A733F
:03007000D40C01AC
:0300710003D03881
:03007200C04A720F
:03007300022C1844
:03007400C0003891
:030075000242192B
:0300760021DE0F79
:0300770003002261
:03007800901C00D9
:030079002020380C
:03007A000302007E
:03007B00901E07CD
:03007C00204F0210
:03007D0003074333
:03007E00901A8352
:03007F00210C0051
:03008000E010315C
:03008100643C12CA
:03008200AC5A90E5
:0300830021020057
:03008400024E0722
:03008500E80F037E
:0300860074374389
:03008700AB2A8C15
:03008800C50C00A4
:03008900039031B0
:03008A00799C1846
:03008B00A8AA9090
:03008C0020BC0095
:03008D00D000316F
:03008E00038C16CA
:03008F00219A9023
:03009000E0703BE2
:03009100348E0F9B
:0300920034808235
:03009300348703AC
:03009400D05A9AA5
:03009500031C0F3A
:03009600C00FFF99
:0300970003215BE7
:030098000331022F
:03009900C70A9BF8
:03009A0003921BB3
:03009B00C500306D
:03009C00039E0FB1
:03009D00C1C03BA4
:03009E00030C024E
:03009F00C0003965
:0300A000031C003E
:0300A100204039C3
:0300A200032C80AC
:0300A300C00D0885
:0300A400033039ED
:0300A500C70C0085
:0300A6000390398B
:0300A700C50C4045
:0300A80003903989
:0300A900C407D9B0
:0300AA00039AA90D
:0300AB0020CC0066
:0300AC0074302687
:0300AD00B1702708
:0300AE00C0002B64
:0300AF00024020EC
:0300B000C05C032E
:0300B10002202CFE
:0300B200205C20AF
:0300B300D20D80EB
:0300B400D4002550
:0300B50003DC2049
:0300B60021D02432
:0300B700030C0037
:0300B80090102283
:0300B900202205FD
:0300BA0003003010
:0300BB0090190198
:0300BC00204204DB
:03009400348A9A11
:03009500030C0F4A
:03009600206FFFD9
:0300970034815B56
:03009800348102AE
:03009900348A9B0B
:03009A0034821B92
:03009B00D0503012
:03009C00031E0F31
:03009D00C0003B65
:03009E00032C022E
:03009F00033039F2
:0300A000C70C008A
:0300A10003903990
:0300A200C50C800A
:0300A300039D08B2
:0300A400C0403920
:0300A500030C0049
:0300A600C000395E
:0300A700031C40F7
:0300A800204039BC
:0300A9000327D951
:0300AA00C00AA9E0
:0300AB00033C0013
:0300AC00C7002664
:0300AD0003902796
:0300AE00C5002B5F
:0300AF000390209B
:0300B000C40C037A
:0300B10003902C8D
:0300B200C40C205B
:0300B300FFFD80CE
:0300B400165025BE
:0300B500D20C204A
:0300B60003D02450
:0300B700C04C003A
:0300B80002202201
:0300B900C002057D
:0300BA00150030FE
:0300BB00024901F6
:0300BC0021D2044A
:0300BD000300300D
:0300BE0090190195
:0300BF00C012026A
:0300C000150030F8
:0300C100024901F0
:0300C20021AC402E
:0300C3009420394D
:0300C400202C01EC
:0300C50003A0375E
:0300C600206C604B
:0300C7007432C8C8
:0300C800AD5AC767
:0300C900C9FC006F
:0300CA0016B03736
:0300CB00C006D993
:0300CC006B0AD0EC
:0300CD00D206F95F
:0300CE006D0B4D6A
:0300CF00D40ACB85
:0300D00012B94022
:0300D100C80C2038
:0300D2001AB195CB
:0300D30020B64311
:0300D400038ADFBD
:0300D500206C019B
:0300D60002A1DFA5
:0300D700C0409B8B
:0300D800086703B3
:0300D900703ADF9B
:0300DA00ADE7D3BC
:0300DB00C00B480F
:0300DC00024CFFD4
:0300DD00AE202230
:0300DE00C04B2AEA
:0300DF000AA21F53
:0300E000C0290A2A
:0300E100024C20AE
:0300E200917125F4
:0300E300C016D371
:0300E40003EAEA42
:0300E500206C206C
:0300E600643095EE
:0300E700AEB6436F
:0300E80037EAF202
:0300E9002C8AEF6F
:0300EA00AE8C4099
:0300EB00C6012526
:0300EC00150C00F0
:0300ED0074302448
:0300EE00AFFB1A4B
:0300EF0021E217F4
:0300F0001AF024DF
:0300F10014FB1AE3
:0300F200743C401B
:0300F300B17105E3
:0300F400C0403DCC
:0300F500124C00AA
:0300F600917024E2
:0300F700C0021D27
:0300F80002403093
:0300F900200901DA
:0300FA0094221538
:0300FB0020203092
:0300FC00020901F5
:0300FD00035204A7
:0300FE00B17030AE
:0300FF00CFF90135
:0301000019E210F1
:0301010016F024D1
:03010200C037F70C
:03010300081B0BCB
:03010400743C0246
:03010500B0EFFF59
:03010600C01164C1
:03010700024C02A5
:030108002001577C
:030109009421241A
:03010A00202B1790
:03010B000207D711
:03010C00035B177B
:03010D00B17C01C1
:03010E00C00FFF20
:03010F0018116460
:03011000643C014B
:030111006B015728
:03011200B14124D4
:03011300B17B17A6
:03011400C01217FF
:0301150012402471
:03011600917B17C3
:03011700369C0211
:03011800C01D0106
:030119001E616400
:03011A0021BC8085
:03011B000866F380
:03011C0074312516
:03011D00A57205C3
:03011E000260304C
:03011F00C02901F3
:03012000FFF215D6
:0301210016B030E5
:03012200C02901F0
:0301230023A20410
:0301240074303004
:0301250012B9010B
:0301260020B7D32C
:03012700038B48FF
:03012800C44210BE
:030129000390221E
:03012A00C40C50B2
:03012B0003903905
:03012C00C0079970
:03012D00023B2C66
:03012E00AC2212EE
:03012F00B2F030FB
:03013000000214B6
:030131000000319A
:03013200000213B5
:0301330000003297
:03013400000C00BC
:0301350000003394
:03013600000C704A
:030137000000398C
:03013800000C5068
:030139000000398A
:03013A00000215AB
:03013B0000003091
:03013C00000C00B4
:03013D000000318E
:03013E00000202BA
:03013F000000328B
:03014000000C00B0
:0301410000003388
:03014200000C703E
:0301430000003980
:03014400000C505C
:030145000000397E
:03014600000C406A
:030147000000397C
:03014800000C00A8
:030149000000397A
:03014A00000C00A6
:03014B00000C00A5
:03014C00000AC2E4
:03014D00000C00A3
:03014E0000002589
:03014F00000C1091
:0301500000003D6F
:030151000009178B
:03015200000C049A
:0301530000002584
:03015400000C009C
:0301550000003D6A
:0301560000091786
:03015700000C0297
:030158000000257F
:03015900000C088F
:03015A0000003D65
:03015B0000091781
:03015C00000C0094
:03015D0000002679
:03015E00000C0191
:03015F0000002974
:03016000000C2070
:0301610000002378
:03016200000A0090
:03016300000B632B
:0300BF00202202FA
:0300C0000300300A
:0300C10090190192
:0300C200204C408F
:0300C300030039FE
:0300C400901C018C
:0300C50020603781
:0300C60090AC609B
:0300C7002052C8FC
:0300C800D20AC792
:0300C900D40C0054
:0300CA0003D03729
:0300CB00C1C6D9D2
:0300CC00022AD035
:0300CD00C006F971
:0300CE00024B4D95
:0300CF0021DACB68
:0300D000030940E1
:0300D100901C2060
:0300D20020219555
:0300D300030643DE
:0300D400901ADFA0
:0300D500204C01BB
:0300D6000301DF44
:0300D70090109BEB
:0300D800210703FA
:0300D900024ADFF9
:0300DA00C037D359
:0300DB00084B4887
:0300DC00603CFF86
:0300DD00AE002250
:0300DE00209B2A3A
:0300DF00AE221F2F
:0300E000C0090A4A
:0300E100AE2C2022
:0300E2001871256D
:0300E3001496D39D
:0300E400643AEA91
:0300E500B11C202B
:0300E6001A7095F8
:0300E700C5064308
:0300E800039AF286
:0300E900799AEF12
:0300EA00AE9C4089
:0300EB0020B1251C
:0300EC00D00C0035
:0300ED0003802469
:0300EE00219B1A39
:0300EF00E07217A5
:0300F00034802435
:0300F100348B1A33
:0300F200348C400B
:0300F30034810550
:0300F40003003DC9
:0300F500206C007C
:0300F6003480242F
:0300F70034821D33
:0300F80034803021
:0300F90034890146
:0300FA00D05215CC
:0300FB00031030BF
:0300FC00C0090137
:0300FD00032204D7
:0300FE000330309C
:0300FF00C709012D
:0301000003921057
:03010100C5002412
:030102000397F769
:03010300C1CB0B62
:03010400030C02E7
:03010500C00FFF29
:030106000311647E
:03010700204C0287
:0301080003215779
:03010900C001240E
:03010A00033B179D
:03010B00C707D74C
:03010C00039B173B
:03010D00C50C011D
:03010E00039FFF4D
:03010F00C40164C4
:03011000039C014C
:0301110020C157B3
:0301120074312421
:03011300B7DB1740
:03011400C002170F
:0301150002402481
:03011600C05B17B4
:03011700022C02B5
:03011800205D0166
:03011900D20164AC
:03011A00D40C8082
:03011B0003D6F315
:03011C0021D125C9
:03011D00030205D5
:03011E009010300E
:03011F0020290193
:03012000030215C2
:030121009010300B
:0301220020490170
:03012300030204D0
:0301240090103008
:03012500C01901FD
:030126001507D3E7
:03012700024B4840
:0301280021A21001
:03012900942022FD
:03012A00202C5036
:03012B0003A039F5
:03012C00206799B0
:03012D00743B2CF4
:03012E00B3B21257
:03012F00C9F030E4
:0301300016B214F0
:03013100C00031DA
:030132006B02134A
:03013300D20032C5
:030134006D0C004F
:03013500D40033C0
:0301360012BC7088
:03013700C80039C4
:030138001ABC509E
:0301390020B039BA
:03013A0003821528
:03013B0020603011
:03013C0002AC0012
:03013D00C040318E
:03013E0008620252
:03013F00703032EB
:03014000B44C00BC
:03014100C00033C8
:03014200024C70FC
:03014300B480394C
:03014400C04C505C
:030145000AA039D4
:03014600C02C408A
:030147000240393A
:03014800917C00A7
:03014900C01039AA
:03014A0003EC00C3
:03014B00206C0025
:03014C00643AC250
:03014D00B51C00DE
:03014E0037E02572
:03014F002C8C10E5
:03015000B4E03DDB
:03015100C60917C5
:03015200150C0485
:03015300743025E0
:03015400B65C0096
:0301550021E03D69
:030156001AF9177C
:0301570014FC0293
:03015800743025DB
:03015900B7DC0808
:03015A00C0403D65
:03015B001249172F
:03015C00917C0093
:03015D00C00026B9
:03015E00024C014F
:03015F0020002954
:03016000942C20BC
:0301610020202338
:03016200020A008E
:03016300035B63D8
:03016400B7D00011
:03016500CFF000D8
:0301660019E0009D
:0301670016F0008F
:03016800C03000A4
:030169000810007B
:03016A00743000EE
:03016B00B740009A
:03016C00C01000C0
:03016D000240004D
:03016E002000006E
:03016F00942000D9
:030170002020004C
:0301710002000089
:0301720003500037
:03017300B7D00002
:03017400C00000C8
:030175001810005F
:03017600643000F2
:030177006B00001A
:03017800B7A0002D
:03017900B7D000FC
:03017A00C01000B2
:03017B001240002F
:03017C009170007F
:03017D00369000B9
:03017E00C01000AE
:03017F001E6000FF
:0301800021B000AB
:0301810008600013
:03018200743000D6
:03018300A5700064
:0301840002600016
:03018500C0200097
:03018600FFF00087
:0301870016B000AF
:03018800C0200094
:0301890023A000B0
:03018A00743000CE
:03018B0012B000AF
:03018C0020B000A0
:03018D00038000EC
:03018E00C440006A
:03018F00039000DA
:03019000C40000A8
:03019100039000D8
:03019200C00000AA
:0301930002300037
:03019400AC20009C
:03019500B950005E
:00000001FF

View File

@ -415,6 +415,9 @@ close STDERR;
exit 0;
__DATA__
* WD 12 02 # Full wave rectified ring detection
* WD 03 01 # Polarity reversal detect mask
* WD 04 00 # Clear interrupt status
* WD 21 08 # Disable PCM transfers
* WD 18 99
* WD 06 00