summaryrefslogtreecommitdiff
path: root/xpp/card_fxo.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_fxo.c')
-rw-r--r--xpp/card_fxo.c76
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);