xpp: FXS type 6: support digital inputs
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
This commit is contained in:
parent
7fcb793cd9
commit
aaa1080a7c
@ -1257,17 +1257,34 @@ static int FXS_card_close(xpd_t *xpd, lineno_t chan)
|
|||||||
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int input_channels[] = { 6, 7, 2, 3 }; // Slic numbers of input relays
|
static int input_ports_type1[] = {
|
||||||
|
/* slic = input_port */
|
||||||
|
[0] = -1,
|
||||||
|
[1] = -1,
|
||||||
|
[2] = 2,
|
||||||
|
[3] = 3,
|
||||||
|
[4] = -1,
|
||||||
|
[5] = -1,
|
||||||
|
[6] = 0,
|
||||||
|
[7] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static void poll_inputs(xpd_t *xpd)
|
static void poll_inputs(xpd_t *xpd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUG_ON(xpd->xbus_idx != 0); // Only unit #0 has digital inputs
|
BUG_ON(xpd->xbus_idx != 0); // Only unit #0 has digital inputs
|
||||||
for (i = 0; i < ARRAY_SIZE(input_channels); i++) {
|
if (XPD_HW(xpd).type == 6) {
|
||||||
__u8 pos = input_channels[i];
|
EXP_REQUEST(xpd->xbus, xpd, SLIC_READ,
|
||||||
|
REG_TYPE6_EXP_GPIOB, 0, 0);
|
||||||
SLIC_DIRECT_REQUEST(xpd->xbus, xpd, pos, SLIC_READ, 0x06, 0);
|
} else {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(input_ports_type1); i++) {
|
||||||
|
int pos = input_ports_type1[i];
|
||||||
|
if (pos >= 0) {
|
||||||
|
XPD_NOTICE(xpd, "%s polling slic %d\n", __func__, i);
|
||||||
|
SLIC_DIRECT_REQUEST(xpd->xbus, xpd, i, SLIC_READ, 0x06, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1529,37 +1546,55 @@ HANDLER_DEF(FXS, SIG_CHANGED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef POLL_DIGITAL_INPUTS
|
#ifdef POLL_DIGITAL_INPUTS
|
||||||
|
static inline void notify_digital_input(xpd_t *xpd, int input_port, int offhook)
|
||||||
|
{
|
||||||
|
int channo = PHONEDEV(xpd).channels - LINES_DIGI_INP + input_port;
|
||||||
|
|
||||||
|
/* Stop ringing. No leds for digital inputs. */
|
||||||
|
PHONEDEV(xpd).ringing[channo] = 0;
|
||||||
|
if (offhook && !IS_OFFHOOK(xpd, channo)) {
|
||||||
|
LINE_DBG(SIGNAL, xpd, channo, "OFFHOOK\n");
|
||||||
|
hookstate_changed(xpd, channo, 1);
|
||||||
|
} else if (!offhook && IS_OFFHOOK(xpd, channo)) {
|
||||||
|
LINE_DBG(SIGNAL, xpd, channo, "ONHOOK\n");
|
||||||
|
hookstate_changed(xpd, channo, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
||||||
{
|
{
|
||||||
int i;
|
bool offhook;
|
||||||
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
|
||||||
xpp_line_t lines = BIT(info->h.portnum);
|
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (!PHONEDEV(xpd).digital_inputs) {
|
if (!PHONEDEV(xpd).digital_inputs) {
|
||||||
XPD_NOTICE(xpd, "%s called without digital inputs. Ignored\n",
|
XPD_NOTICE(xpd, "%s called without digital inputs. Ignored\n",
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Map SLIC number into line number */
|
if (XPD_HW(xpd).type == 6) {
|
||||||
for (i = 0; i < ARRAY_SIZE(input_channels); i++) {
|
static int input_values_type6[] = { 0x80, 0x20, 0x08, 0x02 }; /* I/O Expander values of input relays */
|
||||||
int channo = input_channels[i];
|
int i;
|
||||||
int newchanno;
|
|
||||||
|
|
||||||
if (IS_SET(lines, channo)) {
|
/* Map I/O Expander GPIO into line number */
|
||||||
newchanno = PHONEDEV(xpd).channels - LINES_DIGI_INP + i;
|
for (i = 0; i < ARRAY_SIZE(input_values_type6); i++) {
|
||||||
BIT_CLR(lines, channo);
|
int chanmask = input_values_type6[i];
|
||||||
BIT_SET(lines, newchanno);
|
|
||||||
/* Stop ringing. No leds for digital inputs. */
|
offhook = (REG_FIELD(info, data_low) & chanmask) == 0;
|
||||||
PHONEDEV(xpd).ringing[newchanno] = 0;
|
notify_digital_input(xpd, i, offhook);
|
||||||
if (offhook && !IS_OFFHOOK(xpd, newchanno)) {
|
|
||||||
LINE_DBG(SIGNAL, xpd, newchanno, "OFFHOOK\n");
|
|
||||||
hookstate_changed(xpd, newchanno, 1);
|
|
||||||
} else if (!offhook && IS_OFFHOOK(xpd, newchanno)) {
|
|
||||||
LINE_DBG(SIGNAL, xpd, newchanno, "ONHOOK\n");
|
|
||||||
hookstate_changed(xpd, newchanno, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int channo = info->h.portnum;
|
||||||
|
int input_port;
|
||||||
|
offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
||||||
|
if (channo < 0 || channo >= ARRAY_SIZE(input_ports_type1)) {
|
||||||
|
XPD_ERR(xpd, "%s: got bad portnum=%d\n", __func__, channo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
input_port = input_ports_type1[channo];
|
||||||
|
if (input_port < 0) {
|
||||||
|
XPD_ERR(xpd, "%s: portnum=%d is not input port\n", __func__, channo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notify_digital_input(xpd, input_port, offhook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1668,7 +1703,9 @@ 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 (!indirect && regnum == REG_TYPE1_DIGITAL_IOCTRL)
|
else if ( (XPD_HW(xpd).type == 1 && !indirect && regnum == REG_TYPE1_DIGITAL_IOCTRL) ||
|
||||||
|
(XPD_HW(xpd).type == 6 && !indirect && regnum == REG_TYPE6_EXP_GPIOB &&
|
||||||
|
REG_FIELD(info, do_expander)))
|
||||||
process_digital_inputs(xpd, info);
|
process_digital_inputs(xpd, info);
|
||||||
#endif
|
#endif
|
||||||
else if (XPD_HW(xpd).type == 1 && !indirect && regnum == REG_TYPE1_LOOPCLOSURE) { /* OFFHOOK ? */
|
else if (XPD_HW(xpd).type == 1 && !indirect && regnum == REG_TYPE1_LOOPCLOSURE) { /* OFFHOOK ? */
|
||||||
|
Loading…
Reference in New Issue
Block a user