xpp: fxs: bugfix for 2fxs+6fxo cards
* Bug sympthoms: wrong FSK VMWI sent few seconds after offhook. That was caused because the driver kept polling the (physically unconnected) digital inputs. [note: a workaround for drivers without this patch is to zero the 'xpd_fxs.poll_digital_inputs' parameter.] * Also, the digital_inputs/digital_output masks were calculate using a different condition. * Now we determine number of channels, digital inputs and digital outputs in a single place and use this info later to calculate the correct masks. * We poll only if there are digital_inputs * We added a sanity check in process_digital_inputs, so we get a notice if it's called on an xpd without digital inputs (e.g: hypothetic firmware bug). Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10202 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
d4ee448c7e
commit
1ba9a007d1
@ -386,6 +386,8 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
|
|||||||
int regular_channels;
|
int regular_channels;
|
||||||
struct FXS_priv_data *priv;
|
struct FXS_priv_data *priv;
|
||||||
int i;
|
int i;
|
||||||
|
int d_inputs = 0;
|
||||||
|
int d_outputs = 0;
|
||||||
|
|
||||||
if(!to_phone) {
|
if(!to_phone) {
|
||||||
XBUS_NOTICE(xbus,
|
XBUS_NOTICE(xbus,
|
||||||
@ -398,16 +400,30 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
|
|||||||
else
|
else
|
||||||
regular_channels = min(8, subunit_ports);
|
regular_channels = min(8, subunit_ports);
|
||||||
channels = regular_channels;
|
channels = regular_channels;
|
||||||
if(unit == 0 && subtype != 4)
|
/* Calculate digital inputs/outputs */
|
||||||
|
if(unit == 0 && subtype != 4) {
|
||||||
channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */
|
channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */
|
||||||
|
d_inputs = LINES_DIGI_INP;
|
||||||
|
d_outputs = LINES_DIGI_OUT;
|
||||||
|
}
|
||||||
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXS_priv_data), proto_table, channels);
|
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXS_priv_data), proto_table, channels);
|
||||||
if(!xpd)
|
if(!xpd)
|
||||||
return NULL;
|
return NULL;
|
||||||
if(unit == 0) {
|
/* Initialize digital inputs/outputs */
|
||||||
XBUS_DBG(GENERAL, xbus, "First XPD detected. Initialize digital outputs/inputs\n");
|
if (d_inputs) {
|
||||||
PHONEDEV(xpd).digital_outputs = BITMASK(LINES_DIGI_OUT) << regular_channels;
|
XBUS_DBG(GENERAL, xbus, "Initialize %d digital inputs\n",
|
||||||
PHONEDEV(xpd).digital_inputs = BITMASK(LINES_DIGI_INP) << (regular_channels + LINES_DIGI_OUT);
|
d_inputs);
|
||||||
}
|
PHONEDEV(xpd).digital_inputs =
|
||||||
|
BITMASK(d_inputs) << (regular_channels + d_outputs);
|
||||||
|
} else
|
||||||
|
XBUS_DBG(GENERAL, xbus, "No digital inputs\n");
|
||||||
|
if (d_outputs) {
|
||||||
|
XBUS_DBG(GENERAL, xbus, "Initialize %d digital outputs\n",
|
||||||
|
d_outputs);
|
||||||
|
PHONEDEV(xpd).digital_outputs =
|
||||||
|
BITMASK(d_outputs) << regular_channels;
|
||||||
|
} else
|
||||||
|
XBUS_DBG(GENERAL, xbus, "No digital outputs\n");
|
||||||
PHONEDEV(xpd).direction = TO_PHONE;
|
PHONEDEV(xpd).direction = TO_PHONE;
|
||||||
xpd->type_name = "FXS";
|
xpd->type_name = "FXS";
|
||||||
if(fxs_proc_create(xbus, xpd) < 0)
|
if(fxs_proc_create(xbus, xpd) < 0)
|
||||||
@ -1142,7 +1158,7 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
|
|||||||
priv = xpd->priv;
|
priv = xpd->priv;
|
||||||
BUG_ON(!priv);
|
BUG_ON(!priv);
|
||||||
#ifdef POLL_DIGITAL_INPUTS
|
#ifdef POLL_DIGITAL_INPUTS
|
||||||
if(poll_digital_inputs && xpd->xbus_idx == 0) {
|
if (poll_digital_inputs && PHONEDEV(xpd).digital_inputs) {
|
||||||
if((xpd->timer_count % poll_digital_inputs) == 0)
|
if((xpd->timer_count % poll_digital_inputs) == 0)
|
||||||
poll_inputs(xpd);
|
poll_inputs(xpd);
|
||||||
}
|
}
|
||||||
@ -1254,6 +1270,13 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
|||||||
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
||||||
xpp_line_t lines = BIT(info->portnum);
|
xpp_line_t lines = BIT(info->portnum);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!PHONEDEV(xpd).digital_inputs) {
|
||||||
|
XPD_NOTICE(xpd,
|
||||||
|
"%s called without digital inputs. Ignored\n",
|
||||||
|
__func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Map SLIC number into line number */
|
/* Map SLIC number into line number */
|
||||||
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
|
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
|
||||||
int channo = input_channels[i];
|
int channo = input_channels[i];
|
||||||
@ -1366,7 +1389,7 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
/*
|
/*
|
||||||
* Process digital inputs polling results
|
* Process digital inputs polling results
|
||||||
*/
|
*/
|
||||||
else if(xpd->xbus_idx == 0 && !indirect && regnum == REG_DIGITAL_IOCTRL) {
|
else if (!indirect && regnum == REG_DIGITAL_IOCTRL) {
|
||||||
process_digital_inputs(xpd, info);
|
process_digital_inputs(xpd, info);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user