diff options
Diffstat (limited to 'xpp/card_fxo.c')
-rw-r--r-- | xpp/card_fxo.c | 76 |
1 files changed, 30 insertions, 46 deletions
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c index 7187d08..5d5bdc5 100644 --- a/xpp/card_fxo.c +++ b/xpp/card_fxo.c @@ -29,6 +29,7 @@ #include "xpp_zap.h" #include "card_fxo.h" #include "zap_debug.h" +#include "xbus-core.h" static const char rcsid[] = "$Id$"; @@ -65,7 +66,6 @@ static /* 0x0F */ DECLARE_CMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, /*---------------- FXO Protocol Commands ----------------------------------*/ static /* 0x0F */ DECLARE_CMD(FXO, XPD_STATE, bool on); -static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, lineno_t chan); static /* 0x0F */ DECLARE_CMD(FXO, RING, lineno_t chan, bool on); static /* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on); @@ -152,7 +152,7 @@ static void handle_fxo_leds(xpd_t *xpd) for_each_line(xpd, i) { if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i)) continue; - if(IS_BLINKING(priv,i,color)) { + if(xpd->blink_mode || IS_BLINKING(priv,i,color)) { // led state is toggled if((timer_count % LED_BLINK_PERIOD) == 0) { DBG("%s/%s/%d: ledstate=%s\n", xpd->xbus->busname, xpd->xpdname, i, @@ -421,46 +421,41 @@ static int FXO_card_tick(xbus_t *xbus, xpd_t *xpd) /* FIXME: based on data from from wctdm.h */ #include <wctdm.h> -static const int echotune_reg[] = {30,45,46,47,58,49,50,51,52}; -union echotune { - /* "coeff 0" is acim */ - unsigned char coeff[sizeof(echotune_reg)]; - struct wctdm_echo_coefs wctdm_struct; -}; +/* + * The first register is the ACIM, the other are coefficient registers. + * We define the array size explicitly to track possible inconsistencies + * if the struct is modified. + */ +static const char echotune_regs[sizeof(struct wctdm_echo_coefs)] = {30, 45, 46, 47, 48, 49, 50, 51, 52}; static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long arg) { - union echotune echoregs; - int i,ret; + int i,ret; + unsigned char echotune_data[ARRAY_SIZE(echotune_regs)]; BUG_ON(!xpd); - DBG("cmd: 0x%X, expecting: 0x%X, pos=%d.\n", cmd, WCTDM_SET_ECHOTUNE, pos); switch (cmd) { case WCTDM_SET_ECHOTUNE: DBG("-- Setting echo registers: \n"); /* first off: check if this span is fxs. If not: -EINVALID */ - if (copy_from_user(&echoregs.wctdm_struct, - (struct wctdm_echo_coefs __user *)arg, sizeof(echoregs.wctdm_struct))) + if (copy_from_user(&echotune_data, (void __user *)arg, sizeof(echotune_data))) return -EFAULT; - /* Set the ACIM register */ - /* quick and dirty registers writing: */ - for (i=0; i<sizeof(echotune_reg); i++) { - char buf[22]; - sprintf(buf, "%d WD %2X %2X", - pos,echotune_reg[i],echoregs.coeff[i] - ); - /* FIXME: code duplicated from proc_xpd_register_write */ - ret = handle_register_command(xpd, buf); - if(ret < 0) + for (i = 0; i < ARRAY_SIZE(echotune_regs); i++) { + DBG("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]); return ret; + } msleep(1); } DBG("-- Set echo registers successfully\n"); - break; default: + DBG("%s/%s/%d: Unknown command 0x%X.\n", xpd->xbus->busname, xpd->xpdname, pos, cmd); return -ENOTTY; } return 0; @@ -471,6 +466,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a /* 0x0F */ HOSTCMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high) { int ret = 0; + xframe_t *xframe; xpacket_t *pack; reg_cmd_t *reg_cmd; @@ -478,7 +474,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a DBG("NO XBUS\n"); return -EINVAL; } - XPACKET_NEW(pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id); + XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id); #if 0 DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n", xbus->busname, xpd->xpdname, chipsel, @@ -487,7 +483,6 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a regnum, subreg, data_low, data_high); #endif reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd); - pack->datalen = sizeof(*reg_cmd); reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field REG_FIELD(reg_cmd, chipsel) = chipsel; REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1; @@ -496,7 +491,7 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a REG_FIELD(reg_cmd, subreg) = subreg; REG_FIELD(reg_cmd, data_low) = data_low; REG_FIELD(reg_cmd, data_high) = data_high; - ret = packet_send(xbus, pack); + ret = xframe_send(xbus, xframe); return ret; } @@ -521,17 +516,6 @@ static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on) return ret; } -static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, lineno_t chan) -{ - int ret = 0; - - BUG_ON(!xbus); - BUG_ON(!xpd); - DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan); - return ret; -} - - static /* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on) { BUG_ON(!xbus); @@ -557,7 +541,7 @@ HANDLER_DEF(FXO, SIG_CHANGED) if(!xpd) { NOTICE("%s: received %s for non-existing xpd: %d\n", - __FUNCTION__, cmd->name, XPD_NUM(pack->content.addr)); + __FUNCTION__, cmd->name, XPD_NUM(pack->addr)); return -EPROTO; } priv = xpd->priv; @@ -567,9 +551,10 @@ HANDLER_DEF(FXO, SIG_CHANGED) for_each_line(xpd, i) { if(IS_SET(sig_toggles, i)) { if(!IS_SET(priv->battery, i)) { - DBG("%s/%s/%d: battery is off. ignore false alarm.\n", + DBG("%s/%s/%d: SIG_CHANGED while battery is off.\n", xbus->busname, xpd->xpdname, i); - continue; + // FIXME: allow dialing without battery polling... + // continue; } mark_ring(xpd, i, IS_SET(sig_status, i), 1); } @@ -587,7 +572,7 @@ HANDLER_DEF(FXO, DAA_REPLY) if(!xpd) { NOTICE("%s: received %s for non-existing xpd: %d\n", - __FUNCTION__, cmd->name, XPD_NUM(pack->content.addr)); + __FUNCTION__, cmd->name, XPD_NUM(pack->addr)); return -EPROTO; } spin_lock_irqsave(&xpd->lock, flags); @@ -658,10 +643,8 @@ xproto_table_t PROTO_TABLE(FXO) = { .RING = XPROTO_CALLER(FXO, RING), .RELAY_OUT = XPROTO_CALLER(FXO, RELAY_OUT), .XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE), - .CHAN_CID = XPROTO_CALLER(FXO, CHAN_CID), .SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE), - .PCM_WRITE = XPROTO_CALLER(GLOBAL, PCM_WRITE), }, .packet_is_valid = fxo_packet_is_valid, .packet_dump = fxo_packet_dump, @@ -672,7 +655,7 @@ static bool fxo_packet_is_valid(xpacket_t *pack) const xproto_entry_t *xe; //DBG("\n"); - xe = xproto_card_entry(&PROTO_TABLE(FXO), pack->content.opcode); + xe = xproto_card_entry(&PROTO_TABLE(FXO), pack->opcode); return xe != NULL; } @@ -896,7 +879,7 @@ static int proc_xpd_register_read(char *page, char **start, off_t off, int count int __init card_fxo_startup(void) { - INFO("%s\n", THIS_MODULE->name); + INFO("%s revision %s\n", THIS_MODULE->name, XPP_VERSION); xproto_register(&PROTO_TABLE(FXO)); return 0; } @@ -909,6 +892,7 @@ void __exit card_fxo_cleanup(void) MODULE_DESCRIPTION("XPP FXO Card Driver"); MODULE_AUTHOR("Oron Peled <oron@actcom.co.il>"); MODULE_LICENSE("GPL"); +MODULE_VERSION(XPP_VERSION); MODULE_ALIAS_XPD(XPD_TYPE_FXO); module_init(card_fxo_startup); |