diff options
Diffstat (limited to 'drivers/isdn/mISDN/dsp_core.c')
-rw-r--r-- | drivers/isdn/mISDN/dsp_core.c | 72 |
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) | |||
203 | else if (dsp->dtmf.software) | 203 | else if (dsp->dtmf.software) |
204 | rx_off = 0; | 204 | rx_off = 0; |
205 | /* echo in software */ | 205 | /* echo in software */ |
206 | else if (dsp->echo && dsp->pcm_slot_tx < 0) | 206 | else if (dsp->echo.software) |
207 | rx_off = 0; | 207 | rx_off = 0; |
208 | /* bridge in software */ | 208 | /* bridge in software */ |
209 | else if (dsp->conf) { | 209 | else if (dsp->conf && dsp->conf->software) |
210 | if (dsp->conf->software) | 210 | rx_off = 0; |
211 | rx_off = 0; | 211 | /* data is not required by user space and not required |
212 | } | 212 | * for echo dtmf detection, soft-echo, soft-bridging */ |
213 | 213 | ||
214 | if (rx_off == dsp->rx_is_off) | 214 | if (rx_off == dsp->rx_is_off) |
215 | return; | 215 | return; |
@@ -280,7 +280,7 @@ dsp_fill_empty(struct dsp *dsp) | |||
280 | static int | 280 | static int |
281 | dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) | 281 | dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) |
282 | { | 282 | { |
283 | struct sk_buff *nskb; | 283 | struct sk_buff *nskb; |
284 | int ret = 0; | 284 | int ret = 0; |
285 | int cont; | 285 | int cont; |
286 | u8 *data; | 286 | u8 *data; |
@@ -306,15 +306,18 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) | |||
306 | "to %d\n", *((int *)data)); | 306 | "to %d\n", *((int *)data)); |
307 | dsp->dtmf.treshold = (*(int *)data) * 10000; | 307 | dsp->dtmf.treshold = (*(int *)data) * 10000; |
308 | } | 308 | } |
309 | dsp->dtmf.enable = 1; | ||
309 | /* init goertzel */ | 310 | /* init goertzel */ |
310 | dsp_dtmf_goertzel_init(dsp); | 311 | dsp_dtmf_goertzel_init(dsp); |
311 | 312 | ||
312 | /* check dtmf hardware */ | 313 | /* check dtmf hardware */ |
313 | dsp_dtmf_hardware(dsp); | 314 | dsp_dtmf_hardware(dsp); |
315 | dsp_rx_off(dsp); | ||
314 | break; | 316 | break; |
315 | case DTMF_TONE_STOP: /* turn off DTMF */ | 317 | case DTMF_TONE_STOP: /* turn off DTMF */ |
316 | if (dsp_debug & DEBUG_DSP_CORE) | 318 | if (dsp_debug & DEBUG_DSP_CORE) |
317 | printk(KERN_DEBUG "%s: stop dtmf\n", __func__); | 319 | printk(KERN_DEBUG "%s: stop dtmf\n", __func__); |
320 | dsp->dtmf.enable = 0; | ||
318 | dsp->dtmf.hardware = 0; | 321 | dsp->dtmf.hardware = 0; |
319 | dsp->dtmf.software = 0; | 322 | dsp->dtmf.software = 0; |
320 | break; | 323 | break; |
@@ -414,7 +417,7 @@ tone_off: | |||
414 | dsp_rx_off(dsp); | 417 | dsp_rx_off(dsp); |
415 | break; | 418 | break; |
416 | case DSP_ECHO_ON: /* enable echo */ | 419 | case DSP_ECHO_ON: /* enable echo */ |
417 | dsp->echo = 1; /* soft echo */ | 420 | dsp->echo.software = 1; /* soft echo */ |
418 | if (dsp_debug & DEBUG_DSP_CORE) | 421 | if (dsp_debug & DEBUG_DSP_CORE) |
419 | printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__); | 422 | printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__); |
420 | dsp_cmx_hardware(dsp->conf, dsp); | 423 | dsp_cmx_hardware(dsp->conf, dsp); |
@@ -423,7 +426,8 @@ tone_off: | |||
423 | dsp_cmx_debug(dsp); | 426 | dsp_cmx_debug(dsp); |
424 | break; | 427 | break; |
425 | case DSP_ECHO_OFF: /* disable echo */ | 428 | case DSP_ECHO_OFF: /* disable echo */ |
426 | dsp->echo = 0; | 429 | dsp->echo.software = 0; |
430 | dsp->echo.hardware = 0; | ||
427 | if (dsp_debug & DEBUG_DSP_CORE) | 431 | if (dsp_debug & DEBUG_DSP_CORE) |
428 | printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__); | 432 | printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__); |
429 | dsp_cmx_hardware(dsp->conf, dsp); | 433 | dsp_cmx_hardware(dsp->conf, dsp); |
@@ -556,7 +560,7 @@ tone_off: | |||
556 | dsp->pipeline.inuse = 1; | 560 | dsp->pipeline.inuse = 1; |
557 | dsp_cmx_hardware(dsp->conf, dsp); | 561 | dsp_cmx_hardware(dsp->conf, dsp); |
558 | ret = dsp_pipeline_build(&dsp->pipeline, | 562 | ret = dsp_pipeline_build(&dsp->pipeline, |
559 | len > 0 ? (char *)data : NULL); | 563 | len > 0 ? data : NULL); |
560 | dsp_cmx_hardware(dsp->conf, dsp); | 564 | dsp_cmx_hardware(dsp->conf, dsp); |
561 | dsp_rx_off(dsp); | 565 | dsp_rx_off(dsp); |
562 | } | 566 | } |
@@ -657,11 +661,10 @@ get_features(struct mISDNchannel *ch) | |||
657 | static int | 661 | static int |
658 | dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | 662 | dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) |
659 | { | 663 | { |
660 | struct dsp *dsp = container_of(ch, struct dsp, ch); | 664 | struct dsp *dsp = container_of(ch, struct dsp, ch); |
661 | struct mISDNhead *hh; | 665 | struct mISDNhead *hh; |
662 | int ret = 0; | 666 | int ret = 0; |
663 | u8 *digits; | 667 | u8 *digits = NULL; |
664 | int cont; | ||
665 | u_long flags; | 668 | u_long flags; |
666 | 669 | ||
667 | hh = mISDN_HEAD_P(skb); | 670 | hh = mISDN_HEAD_P(skb); |
@@ -704,50 +707,55 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | |||
704 | break; | 707 | break; |
705 | } | 708 | } |
706 | 709 | ||
710 | spin_lock_irqsave(&dsp_lock, flags); | ||
711 | |||
707 | /* decrypt if enabled */ | 712 | /* decrypt if enabled */ |
708 | if (dsp->bf_enable) | 713 | if (dsp->bf_enable) |
709 | dsp_bf_decrypt(dsp, skb->data, skb->len); | 714 | dsp_bf_decrypt(dsp, skb->data, skb->len); |
710 | /* pipeline */ | 715 | /* pipeline */ |
711 | if (dsp->pipeline.inuse) | 716 | if (dsp->pipeline.inuse) |
712 | dsp_pipeline_process_rx(&dsp->pipeline, skb->data, | 717 | dsp_pipeline_process_rx(&dsp->pipeline, skb->data, |
713 | skb->len); | 718 | skb->len, hh->id); |
714 | /* change volume if requested */ | 719 | /* change volume if requested */ |
715 | if (dsp->rx_volume) | 720 | if (dsp->rx_volume) |
716 | dsp_change_volume(skb, dsp->rx_volume); | 721 | dsp_change_volume(skb, dsp->rx_volume); |
717 | |||
718 | /* check if dtmf soft decoding is turned on */ | 722 | /* check if dtmf soft decoding is turned on */ |
719 | if (dsp->dtmf.software) { | 723 | if (dsp->dtmf.software) { |
720 | digits = dsp_dtmf_goertzel_decode(dsp, skb->data, | 724 | digits = dsp_dtmf_goertzel_decode(dsp, skb->data, |
721 | skb->len, (dsp_options&DSP_OPT_ULAW)?1:0); | 725 | skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0); |
726 | } | ||
727 | /* we need to process receive data if software */ | ||
728 | if (dsp->conf && dsp->conf->software) { | ||
729 | /* process data from card at cmx */ | ||
730 | dsp_cmx_receive(dsp, skb); | ||
731 | } | ||
732 | |||
733 | spin_unlock_irqrestore(&dsp_lock, flags); | ||
734 | |||
735 | /* send dtmf result, if any */ | ||
736 | if (digits) { | ||
722 | while (*digits) { | 737 | while (*digits) { |
738 | int k; | ||
723 | struct sk_buff *nskb; | 739 | struct sk_buff *nskb; |
724 | if (dsp_debug & DEBUG_DSP_DTMF) | 740 | if (dsp_debug & DEBUG_DSP_DTMF) |
725 | printk(KERN_DEBUG "%s: digit" | 741 | printk(KERN_DEBUG "%s: digit" |
726 | "(%c) to layer %s\n", | 742 | "(%c) to layer %s\n", |
727 | __func__, *digits, dsp->name); | 743 | __func__, *digits, dsp->name); |
728 | cont = DTMF_TONE_VAL | *digits; | 744 | k = *digits | DTMF_TONE_VAL; |
729 | nskb = _alloc_mISDN_skb(PH_CONTROL_IND, | 745 | nskb = _alloc_mISDN_skb(PH_CONTROL_IND, |
730 | MISDN_ID_ANY, sizeof(int), &cont, | 746 | MISDN_ID_ANY, sizeof(int), &k, |
731 | GFP_ATOMIC); | 747 | GFP_ATOMIC); |
732 | if (nskb) { | 748 | if (nskb) { |
733 | if (dsp->up) { | 749 | if (dsp->up) { |
734 | if (dsp->up->send( | 750 | if (dsp->up->send( |
735 | dsp->up, nskb)) | 751 | dsp->up, nskb)) |
736 | dev_kfree_skb(nskb); | 752 | dev_kfree_skb(nskb); |
737 | } else | 753 | } else |
738 | dev_kfree_skb(nskb); | 754 | dev_kfree_skb(nskb); |
739 | } | 755 | } |
740 | digits++; | 756 | digits++; |
741 | } | 757 | } |
742 | } | 758 | } |
743 | /* we need to process receive data if software */ | ||
744 | spin_lock_irqsave(&dsp_lock, flags); | ||
745 | if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) { | ||
746 | /* process data from card at cmx */ | ||
747 | dsp_cmx_receive(dsp, skb); | ||
748 | } | ||
749 | spin_unlock_irqrestore(&dsp_lock, flags); | ||
750 | |||
751 | if (dsp->rx_disabled) { | 759 | if (dsp->rx_disabled) { |
752 | /* if receive is not allowed */ | 760 | /* if receive is not allowed */ |
753 | break; | 761 | break; |
@@ -787,7 +795,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | |||
787 | if (dsp->up) { | 795 | if (dsp->up) { |
788 | if (dsp->up->send( | 796 | if (dsp->up->send( |
789 | dsp->up, nskb)) | 797 | dsp->up, nskb)) |
790 | dev_kfree_skb(nskb); | 798 | dev_kfree_skb(nskb); |
791 | } else | 799 | } else |
792 | dev_kfree_skb(nskb); | 800 | dev_kfree_skb(nskb); |
793 | } | 801 | } |
@@ -946,7 +954,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
946 | int err = 0; | 954 | int err = 0; |
947 | 955 | ||
948 | if (debug & DEBUG_DSP_CTRL) | 956 | if (debug & DEBUG_DSP_CTRL) |
949 | printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); | 957 | printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); |
950 | 958 | ||
951 | switch (cmd) { | 959 | switch (cmd) { |
952 | case OPEN_CHANNEL: | 960 | case OPEN_CHANNEL: |
@@ -1169,9 +1177,9 @@ static int dsp_init(void) | |||
1169 | 1177 | ||
1170 | /* init conversion tables */ | 1178 | /* init conversion tables */ |
1171 | dsp_audio_generate_law_tables(); | 1179 | dsp_audio_generate_law_tables(); |
1172 | dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a; | 1180 | dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a; |
1173 | dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32: | 1181 | dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ? |
1174 | dsp_audio_alaw_to_s32; | 1182 | dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32; |
1175 | dsp_audio_generate_s2law_table(); | 1183 | dsp_audio_generate_s2law_table(); |
1176 | dsp_audio_generate_seven(); | 1184 | dsp_audio_generate_seven(); |
1177 | dsp_audio_generate_mix_table(); | 1185 | dsp_audio_generate_mix_table(); |