aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/dsp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/dsp_core.c')
-rw-r--r--drivers/isdn/mISDN/dsp_core.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 47dbfe298b43..77ee2867c8b4 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -203,13 +203,13 @@ dsp_rx_off_member(struct dsp *dsp)
else if (dsp->dtmf.software)
rx_off = 0;
/* echo in software */
- else if (dsp->echo && dsp->pcm_slot_tx < 0)
+ else if (dsp->echo.software)
rx_off = 0;
/* bridge in software */
- else if (dsp->conf) {
- if (dsp->conf->software)
- rx_off = 0;
- }
+ else if (dsp->conf && dsp->conf->software)
+ rx_off = 0;
+ /* data is not required by user space and not required
+ * for echo dtmf detection, soft-echo, soft-bridging */
if (rx_off == dsp->rx_is_off)
return;
@@ -280,7 +280,7 @@ dsp_fill_empty(struct dsp *dsp)
static int
dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
{
- struct sk_buff *nskb;
+ struct sk_buff *nskb;
int ret = 0;
int cont;
u8 *data;
@@ -306,15 +306,18 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
"to %d\n", *((int *)data));
dsp->dtmf.treshold = (*(int *)data) * 10000;
}
+ dsp->dtmf.enable = 1;
/* init goertzel */
dsp_dtmf_goertzel_init(dsp);
/* check dtmf hardware */
dsp_dtmf_hardware(dsp);
+ dsp_rx_off(dsp);
break;
case DTMF_TONE_STOP: /* turn off DTMF */
if (dsp_debug & DEBUG_DSP_CORE)
printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
+ dsp->dtmf.enable = 0;
dsp->dtmf.hardware = 0;
dsp->dtmf.software = 0;
break;
@@ -414,7 +417,7 @@ tone_off:
dsp_rx_off(dsp);
break;
case DSP_ECHO_ON: /* enable echo */
- dsp->echo = 1; /* soft echo */
+ dsp->echo.software = 1; /* soft echo */
if (dsp_debug & DEBUG_DSP_CORE)
printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
dsp_cmx_hardware(dsp->conf, dsp);
@@ -423,7 +426,8 @@ tone_off:
dsp_cmx_debug(dsp);
break;
case DSP_ECHO_OFF: /* disable echo */
- dsp->echo = 0;
+ dsp->echo.software = 0;
+ dsp->echo.hardware = 0;
if (dsp_debug & DEBUG_DSP_CORE)
printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
dsp_cmx_hardware(dsp->conf, dsp);
@@ -556,7 +560,7 @@ tone_off:
dsp->pipeline.inuse = 1;
dsp_cmx_hardware(dsp->conf, dsp);
ret = dsp_pipeline_build(&dsp->pipeline,
- len > 0 ? (char *)data : NULL);
+ len > 0 ? data : NULL);
dsp_cmx_hardware(dsp->conf, dsp);
dsp_rx_off(dsp);
}
@@ -657,11 +661,10 @@ get_features(struct mISDNchannel *ch)
static int
dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
{
- struct dsp *dsp = container_of(ch, struct dsp, ch);
+ struct dsp *dsp = container_of(ch, struct dsp, ch);
struct mISDNhead *hh;
int ret = 0;
- u8 *digits;
- int cont;
+ u8 *digits = NULL;
u_long flags;
hh = mISDN_HEAD_P(skb);
@@ -704,50 +707,55 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
break;
}
+ spin_lock_irqsave(&dsp_lock, flags);
+
/* decrypt if enabled */
if (dsp->bf_enable)
dsp_bf_decrypt(dsp, skb->data, skb->len);
/* pipeline */
if (dsp->pipeline.inuse)
dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
- skb->len);
+ skb->len, hh->id);
/* change volume if requested */
if (dsp->rx_volume)
dsp_change_volume(skb, dsp->rx_volume);
-
/* check if dtmf soft decoding is turned on */
if (dsp->dtmf.software) {
digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
- skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
+ skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
+ }
+ /* we need to process receive data if software */
+ if (dsp->conf && dsp->conf->software) {
+ /* process data from card at cmx */
+ dsp_cmx_receive(dsp, skb);
+ }
+
+ spin_unlock_irqrestore(&dsp_lock, flags);
+
+ /* send dtmf result, if any */
+ if (digits) {
while (*digits) {
+ int k;
struct sk_buff *nskb;
if (dsp_debug & DEBUG_DSP_DTMF)
printk(KERN_DEBUG "%s: digit"
"(%c) to layer %s\n",
__func__, *digits, dsp->name);
- cont = DTMF_TONE_VAL | *digits;
+ k = *digits | DTMF_TONE_VAL;
nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
- MISDN_ID_ANY, sizeof(int), &cont,
- GFP_ATOMIC);
+ MISDN_ID_ANY, sizeof(int), &k,
+ GFP_ATOMIC);
if (nskb) {
if (dsp->up) {
if (dsp->up->send(
dsp->up, nskb))
- dev_kfree_skb(nskb);
+ dev_kfree_skb(nskb);
} else
dev_kfree_skb(nskb);
}
digits++;
}
}
- /* we need to process receive data if software */
- spin_lock_irqsave(&dsp_lock, flags);
- if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
- /* process data from card at cmx */
- dsp_cmx_receive(dsp, skb);
- }
- spin_unlock_irqrestore(&dsp_lock, flags);
-
if (dsp->rx_disabled) {
/* if receive is not allowed */
break;
@@ -787,7 +795,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
if (dsp->up) {
if (dsp->up->send(
dsp->up, nskb))
- dev_kfree_skb(nskb);
+ dev_kfree_skb(nskb);
} else
dev_kfree_skb(nskb);
}
@@ -946,7 +954,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
int err = 0;
if (debug & DEBUG_DSP_CTRL)
- printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
+ printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
switch (cmd) {
case OPEN_CHANNEL:
@@ -1169,9 +1177,9 @@ static int dsp_init(void)
/* init conversion tables */
dsp_audio_generate_law_tables();
- dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a;
- dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32:
- dsp_audio_alaw_to_s32;
+ dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
+ dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
+ dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
dsp_audio_generate_s2law_table();
dsp_audio_generate_seven();
dsp_audio_generate_mix_table();