Lines Matching +full:conf +full:- +full:rx

20  * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect
21 * 1-n = hardware-conference. The n will give the conference number.
39 * - Crossconnecting or even conference, if more than two members are together.
40 * - Force mixing of transmit data with other crossconnect/conference members.
41 * - Echo generation to benchmark the delay of audio processing.
42 * - Use hardware to minimize cpu load, disable FIFO load and minimize delay.
43 * - Dejittering and clock generation.
48 * RX-Buffer
51 * ----------------+-------------+-------------------
53 * The rx-buffer is a ring buffer used to store the received data for each
56 * The transmit-clock (R) will read the buffer.
57 * If the clock overruns the write-pointer, we will have a buffer underrun.
58 * If the write pointer always has a certain distance from the transmit-
63 * TX-Buffer
66 * -----------------+--------+-----------------------
68 * The tx-buffer is a ring buffer to queue the transmit data from user space
82 * - has multiple clocks.
83 * - has no usable clock due to jitter or packet loss (VoIP).
89 * - If a member joins, its rx_buff is set to silence and change read pointer
103 * Changing rx-volume is done before the data is crossconnected. The tx-volume
108 * the card. It will replace the tx-data from the user space.
112 * Disable rx-data:
113 * If cmx is realized in hardware, rx data will be disabled if requested by
114 * the upper layer. If dtmf decoding is done by software and enabled, rx data
119 * used if not forbidden by control command. Disabling rx-data provides
120 * absolutely traffic free audio processing. (except for the quick 1-frame
141 /*#define CMX_DELAY_DEBUG * gives rx-buffer delay overview */
142 /*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
150 struct dsp_conf *conf; in dsp_cmx_debug() local
154 printk(KERN_DEBUG "-----Current DSP\n"); in dsp_cmx_debug()
157 odsp->name, odsp->echo.hardware, odsp->echo.software, in dsp_cmx_debug()
158 odsp->tx_mix); in dsp_cmx_debug()
159 if (odsp->conf) in dsp_cmx_debug()
160 printk(" (Conf %d)", odsp->conf->id); in dsp_cmx_debug()
165 printk(KERN_DEBUG "-----Current Conf:\n"); in dsp_cmx_debug()
166 list_for_each_entry(conf, &conf_ilist, list) { in dsp_cmx_debug()
167 printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf); in dsp_cmx_debug()
168 list_for_each_entry(member, &conf->mlist, list) { in dsp_cmx_debug()
170 " - member = %s (slot_tx %d, bank_tx %d, " in dsp_cmx_debug()
173 member->dsp->name, member->dsp->pcm_slot_tx, in dsp_cmx_debug()
174 member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, in dsp_cmx_debug()
175 member->dsp->pcm_bank_rx, member->dsp->hfc_conf, in dsp_cmx_debug()
176 member->dsp->tx_data, member->dsp->rx_is_off, in dsp_cmx_debug()
177 (member->dsp == dsp) ? " *this*" : ""); in dsp_cmx_debug()
180 printk(KERN_DEBUG "-----end\n"); in dsp_cmx_debug()
189 struct dsp_conf *conf; in dsp_cmx_search_conf() local
197 list_for_each_entry(conf, &conf_ilist, list) in dsp_cmx_search_conf()
198 if (conf->id == id) in dsp_cmx_search_conf()
199 return conf; in dsp_cmx_search_conf()
209 dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf) in dsp_cmx_add_conf_member() argument
213 if (!conf || !dsp) { in dsp_cmx_add_conf_member()
214 printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__); in dsp_cmx_add_conf_member()
215 return -EINVAL; in dsp_cmx_add_conf_member()
217 if (dsp->member) { in dsp_cmx_add_conf_member()
218 printk(KERN_WARNING "%s: dsp is already member in a conf.\n", in dsp_cmx_add_conf_member()
220 return -EINVAL; in dsp_cmx_add_conf_member()
223 if (dsp->conf) { in dsp_cmx_add_conf_member()
224 printk(KERN_WARNING "%s: dsp is already in a conf.\n", in dsp_cmx_add_conf_member()
226 return -EINVAL; in dsp_cmx_add_conf_member()
232 return -ENOMEM; in dsp_cmx_add_conf_member()
234 member->dsp = dsp; in dsp_cmx_add_conf_member()
235 /* clear rx buffer */ in dsp_cmx_add_conf_member()
236 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); in dsp_cmx_add_conf_member()
237 dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */ in dsp_cmx_add_conf_member()
238 dsp->rx_W = 0; in dsp_cmx_add_conf_member()
239 dsp->rx_R = 0; in dsp_cmx_add_conf_member()
241 list_add_tail(&member->list, &conf->mlist); in dsp_cmx_add_conf_member()
243 dsp->conf = conf; in dsp_cmx_add_conf_member()
244 dsp->member = member; in dsp_cmx_add_conf_member()
261 return -EINVAL; in dsp_cmx_del_conf_member()
264 if (!dsp->conf) { in dsp_cmx_del_conf_member()
265 printk(KERN_WARNING "%s: dsp is not in a conf.\n", in dsp_cmx_del_conf_member()
267 return -EINVAL; in dsp_cmx_del_conf_member()
270 if (list_empty(&dsp->conf->mlist)) { in dsp_cmx_del_conf_member()
271 printk(KERN_WARNING "%s: dsp has linked an empty conf.\n", in dsp_cmx_del_conf_member()
273 return -EINVAL; in dsp_cmx_del_conf_member()
276 /* find us in conf */ in dsp_cmx_del_conf_member()
277 list_for_each_entry(member, &dsp->conf->mlist, list) { in dsp_cmx_del_conf_member()
278 if (member->dsp == dsp) { in dsp_cmx_del_conf_member()
279 list_del(&member->list); in dsp_cmx_del_conf_member()
280 dsp->conf = NULL; in dsp_cmx_del_conf_member()
281 dsp->member = NULL; in dsp_cmx_del_conf_member()
290 return -EINVAL; in dsp_cmx_del_conf_member()
300 struct dsp_conf *conf; in dsp_cmx_new_conf() local
308 conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); in dsp_cmx_new_conf()
309 if (!conf) { in dsp_cmx_new_conf()
313 INIT_LIST_HEAD(&conf->mlist); in dsp_cmx_new_conf()
314 conf->id = id; in dsp_cmx_new_conf()
316 list_add_tail(&conf->list, &conf_ilist); in dsp_cmx_new_conf()
318 return conf; in dsp_cmx_new_conf()
326 dsp_cmx_del_conf(struct dsp_conf *conf) in dsp_cmx_del_conf() argument
328 if (!conf) { in dsp_cmx_del_conf()
329 printk(KERN_WARNING "%s: conf is null.\n", in dsp_cmx_del_conf()
331 return -EINVAL; in dsp_cmx_del_conf()
334 if (!list_empty(&conf->mlist)) { in dsp_cmx_del_conf()
335 printk(KERN_WARNING "%s: conf not empty.\n", in dsp_cmx_del_conf()
337 return -EINVAL; in dsp_cmx_del_conf()
339 list_del(&conf->list); in dsp_cmx_del_conf()
340 kfree(conf); in dsp_cmx_del_conf()
359 if (dsp->ch.peer) in dsp_cmx_hw_message()
360 dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq); in dsp_cmx_hw_message()
368 * if only dsp instance is given, the instance is not associated with a conf
373 dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp) in dsp_cmx_hardware() argument
380 int same_hfc = -1, same_pcm = -1, current_conf = -1, in dsp_cmx_hardware()
383 /* dsp gets updated (no conf) */ in dsp_cmx_hardware()
384 if (!conf) { in dsp_cmx_hardware()
389 __func__, dsp->name); in dsp_cmx_hardware()
392 if (dsp->hfc_conf >= 0) { in dsp_cmx_hardware()
395 "%s removing %s from HFC conf %d " in dsp_cmx_hardware()
397 dsp->name, dsp->hfc_conf); in dsp_cmx_hardware()
400 dsp->hfc_conf = -1; in dsp_cmx_hardware()
403 if (dsp->features.pcm_banks < 1) in dsp_cmx_hardware()
405 if (!dsp->echo.software && !dsp->echo.hardware) { in dsp_cmx_hardware()
407 if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) { in dsp_cmx_hardware()
410 " PCM slot %d (TX) %d (RX) because" in dsp_cmx_hardware()
412 __func__, dsp->name, in dsp_cmx_hardware()
413 dsp->pcm_slot_tx, dsp->pcm_slot_rx); in dsp_cmx_hardware()
416 dsp->pcm_slot_tx = -1; in dsp_cmx_hardware()
417 dsp->pcm_bank_tx = -1; in dsp_cmx_hardware()
418 dsp->pcm_slot_rx = -1; in dsp_cmx_hardware()
419 dsp->pcm_bank_rx = -1; in dsp_cmx_hardware()
424 dsp->echo.software = dsp->tx_data; in dsp_cmx_hardware()
425 dsp->echo.hardware = 0; in dsp_cmx_hardware()
427 if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 && in dsp_cmx_hardware()
428 dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) { in dsp_cmx_hardware()
429 dsp->echo.hardware = 1; in dsp_cmx_hardware()
433 if (dsp->pcm_slot_tx >= 0) { in dsp_cmx_hardware()
434 dsp->pcm_slot_rx = dsp->pcm_slot_tx; in dsp_cmx_hardware()
435 dsp->pcm_bank_tx = 2; /* 2 means loop */ in dsp_cmx_hardware()
436 dsp->pcm_bank_rx = 2; in dsp_cmx_hardware()
440 __func__, dsp->name, in dsp_cmx_hardware()
441 dsp->pcm_slot_tx); in dsp_cmx_hardware()
443 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); in dsp_cmx_hardware()
444 dsp->echo.hardware = 1; in dsp_cmx_hardware()
448 dsp->pcm_slot_tx = -1; in dsp_cmx_hardware()
449 dsp->pcm_slot_rx = -1; in dsp_cmx_hardware()
452 if (finddsp->features.pcm_id == dsp->features.pcm_id) { in dsp_cmx_hardware()
453 if (finddsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
454 finddsp->pcm_slot_rx < sizeof(freeslots)) in dsp_cmx_hardware()
455 freeslots[finddsp->pcm_slot_rx] = 0; in dsp_cmx_hardware()
456 if (finddsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
457 finddsp->pcm_slot_tx < sizeof(freeslots)) in dsp_cmx_hardware()
458 freeslots[finddsp->pcm_slot_tx] = 0; in dsp_cmx_hardware()
462 ii = dsp->features.pcm_slots; in dsp_cmx_hardware()
474 dsp->echo.software = 1; in dsp_cmx_hardware()
478 dsp->pcm_slot_tx = i; in dsp_cmx_hardware()
479 dsp->pcm_slot_rx = i; in dsp_cmx_hardware()
480 dsp->pcm_bank_tx = 2; /* loop */ in dsp_cmx_hardware()
481 dsp->pcm_bank_rx = 2; in dsp_cmx_hardware()
485 __func__, dsp->name, dsp->pcm_slot_tx); in dsp_cmx_hardware()
487 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); in dsp_cmx_hardware()
488 dsp->echo.hardware = 1; in dsp_cmx_hardware()
492 /* conf gets updated (all members) */ in dsp_cmx_hardware()
495 __func__, conf->id); in dsp_cmx_hardware()
497 if (list_empty(&conf->mlist)) { in dsp_cmx_hardware()
502 member = list_entry(conf->mlist.next, struct dsp_conf_member, list); in dsp_cmx_hardware()
503 same_hfc = member->dsp->features.hfc_id; in dsp_cmx_hardware()
504 same_pcm = member->dsp->features.pcm_id; in dsp_cmx_hardware()
506 list_for_each_entry(member, &conf->mlist, list) { in dsp_cmx_hardware()
508 if (member->dsp->tx_mix) { in dsp_cmx_hardware()
511 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
513 member->dsp->name); in dsp_cmx_hardware()
515 list_for_each_entry(member, &conf->mlist, list) { in dsp_cmx_hardware()
516 dsp = member->dsp; in dsp_cmx_hardware()
518 if (dsp->hfc_conf >= 0) { in dsp_cmx_hardware()
522 "conf %d because not " in dsp_cmx_hardware()
525 dsp->name, in dsp_cmx_hardware()
526 dsp->hfc_conf); in dsp_cmx_hardware()
530 dsp->hfc_conf = -1; in dsp_cmx_hardware()
533 if (dsp->pcm_slot_tx >= 0 || in dsp_cmx_hardware()
534 dsp->pcm_slot_rx >= 0) { in dsp_cmx_hardware()
538 " slot %d (RX) because not" in dsp_cmx_hardware()
541 dsp->name, in dsp_cmx_hardware()
542 dsp->pcm_slot_tx, in dsp_cmx_hardware()
543 dsp->pcm_slot_rx); in dsp_cmx_hardware()
547 dsp->pcm_slot_tx = -1; in dsp_cmx_hardware()
548 dsp->pcm_bank_tx = -1; in dsp_cmx_hardware()
549 dsp->pcm_slot_rx = -1; in dsp_cmx_hardware()
550 dsp->pcm_bank_rx = -1; in dsp_cmx_hardware()
553 conf->hardware = 0; in dsp_cmx_hardware()
554 conf->software = 1; in dsp_cmx_hardware()
558 if (member->dsp->echo.hardware || member->dsp->echo.software) { in dsp_cmx_hardware()
561 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
563 member->dsp->name); in dsp_cmx_hardware()
567 if (member->dsp->tx_mix) { in dsp_cmx_hardware()
570 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
572 __func__, member->dsp->name); in dsp_cmx_hardware()
576 if (member->dsp->tx_volume) { in dsp_cmx_hardware()
579 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
581 __func__, member->dsp->name); in dsp_cmx_hardware()
584 if (member->dsp->rx_volume) { in dsp_cmx_hardware()
587 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
589 __func__, member->dsp->name); in dsp_cmx_hardware()
592 /* check if tx-data turned on */ in dsp_cmx_hardware()
593 if (member->dsp->tx_data) { in dsp_cmx_hardware()
597 __func__, member->dsp->name); in dsp_cmx_hardware()
601 if (member->dsp->pipeline.inuse) { in dsp_cmx_hardware()
604 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
606 member->dsp->name); in dsp_cmx_hardware()
610 if (member->dsp->bf_enable) { in dsp_cmx_hardware()
613 "conf, because encryption is enabled\n", in dsp_cmx_hardware()
614 __func__, member->dsp->name); in dsp_cmx_hardware()
618 if (member->dsp->features.pcm_id < 0) { in dsp_cmx_hardware()
621 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
623 __func__, member->dsp->name); in dsp_cmx_hardware()
627 if (member->dsp->features.pcm_id != same_pcm) { in dsp_cmx_hardware()
630 "%s dsp %s cannot form a conf, because " in dsp_cmx_hardware()
633 __func__, member->dsp->name); in dsp_cmx_hardware()
637 if (same_hfc != member->dsp->features.hfc_id) in dsp_cmx_hardware()
638 same_hfc = -1; in dsp_cmx_hardware()
640 if (current_conf < 0 && member->dsp->hfc_conf >= 0) in dsp_cmx_hardware()
641 current_conf = member->dsp->hfc_conf; in dsp_cmx_hardware()
643 if (member->dsp->hfc_conf < 0) in dsp_cmx_hardware()
657 "%s conf %d cannot form a HW conference, " in dsp_cmx_hardware()
658 "because dsp is alone\n", __func__, conf->id); in dsp_cmx_hardware()
659 conf->hardware = 0; in dsp_cmx_hardware()
660 conf->software = 0; in dsp_cmx_hardware()
661 member = list_entry(conf->mlist.next, struct dsp_conf_member, in dsp_cmx_hardware()
663 dsp = member->dsp; in dsp_cmx_hardware()
675 member = list_entry(conf->mlist.next, struct dsp_conf_member, in dsp_cmx_hardware()
677 nextm = list_entry(member->list.next, struct dsp_conf_member, in dsp_cmx_hardware()
680 if (member->dsp->hfc_conf >= 0) { in dsp_cmx_hardware()
683 "%s removing %s from HFC conf %d because " in dsp_cmx_hardware()
685 __func__, member->dsp->name, in dsp_cmx_hardware()
686 member->dsp->hfc_conf); in dsp_cmx_hardware()
687 dsp_cmx_hw_message(member->dsp, in dsp_cmx_hardware()
689 member->dsp->hfc_conf = -1; in dsp_cmx_hardware()
691 if (nextm->dsp->hfc_conf >= 0) { in dsp_cmx_hardware()
694 "%s removing %s from HFC conf %d because " in dsp_cmx_hardware()
696 __func__, nextm->dsp->name, in dsp_cmx_hardware()
697 nextm->dsp->hfc_conf); in dsp_cmx_hardware()
698 dsp_cmx_hw_message(nextm->dsp, in dsp_cmx_hardware()
700 nextm->dsp->hfc_conf = -1; in dsp_cmx_hardware()
703 if (member->dsp->features.pcm_banks > 1 && in dsp_cmx_hardware()
704 nextm->dsp->features.pcm_banks > 1 && in dsp_cmx_hardware()
705 member->dsp->features.hfc_id != in dsp_cmx_hardware()
706 nextm->dsp->features.hfc_id) { in dsp_cmx_hardware()
708 if (member->dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
709 member->dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
710 nextm->dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
711 nextm->dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
712 nextm->dsp->pcm_slot_tx == in dsp_cmx_hardware()
713 member->dsp->pcm_slot_rx && in dsp_cmx_hardware()
714 nextm->dsp->pcm_slot_rx == in dsp_cmx_hardware()
715 member->dsp->pcm_slot_tx && in dsp_cmx_hardware()
716 nextm->dsp->pcm_slot_tx == in dsp_cmx_hardware()
717 member->dsp->pcm_slot_tx && in dsp_cmx_hardware()
718 member->dsp->pcm_bank_tx != in dsp_cmx_hardware()
719 member->dsp->pcm_bank_rx && in dsp_cmx_hardware()
720 nextm->dsp->pcm_bank_tx != in dsp_cmx_hardware()
721 nextm->dsp->pcm_bank_rx) { in dsp_cmx_hardware()
727 "(RX) (on different chips)\n", in dsp_cmx_hardware()
729 member->dsp->name, in dsp_cmx_hardware()
730 nextm->dsp->name, in dsp_cmx_hardware()
731 member->dsp->pcm_slot_tx, in dsp_cmx_hardware()
732 member->dsp->pcm_bank_tx, in dsp_cmx_hardware()
733 member->dsp->pcm_bank_rx); in dsp_cmx_hardware()
734 conf->hardware = 1; in dsp_cmx_hardware()
735 conf->software = tx_data; in dsp_cmx_hardware()
741 if (dsp != member->dsp && in dsp_cmx_hardware()
742 dsp != nextm->dsp && in dsp_cmx_hardware()
743 member->dsp->features.pcm_id == in dsp_cmx_hardware()
744 dsp->features.pcm_id) { in dsp_cmx_hardware()
745 if (dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
746 dsp->pcm_slot_rx < in dsp_cmx_hardware()
748 freeslots[dsp->pcm_slot_rx] = 0; in dsp_cmx_hardware()
749 if (dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
750 dsp->pcm_slot_tx < in dsp_cmx_hardware()
752 freeslots[dsp->pcm_slot_tx] = 0; in dsp_cmx_hardware()
756 ii = member->dsp->features.pcm_slots; in dsp_cmx_hardware()
767 member->dsp->name, in dsp_cmx_hardware()
768 nextm->dsp->name); in dsp_cmx_hardware()
773 member->dsp->pcm_slot_tx = i; in dsp_cmx_hardware()
774 member->dsp->pcm_slot_rx = i; in dsp_cmx_hardware()
775 nextm->dsp->pcm_slot_tx = i; in dsp_cmx_hardware()
776 nextm->dsp->pcm_slot_rx = i; in dsp_cmx_hardware()
777 member->dsp->pcm_bank_rx = 0; in dsp_cmx_hardware()
778 member->dsp->pcm_bank_tx = 1; in dsp_cmx_hardware()
779 nextm->dsp->pcm_bank_rx = 1; in dsp_cmx_hardware()
780 nextm->dsp->pcm_bank_tx = 0; in dsp_cmx_hardware()
784 "(TX and RX on different chips) because " in dsp_cmx_hardware()
787 member->dsp->name, in dsp_cmx_hardware()
788 nextm->dsp->name, in dsp_cmx_hardware()
789 member->dsp->pcm_slot_tx); in dsp_cmx_hardware()
790 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, in dsp_cmx_hardware()
791 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, in dsp_cmx_hardware()
792 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); in dsp_cmx_hardware()
793 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, in dsp_cmx_hardware()
794 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, in dsp_cmx_hardware()
795 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); in dsp_cmx_hardware()
796 conf->hardware = 1; in dsp_cmx_hardware()
797 conf->software = tx_data; in dsp_cmx_hardware()
802 if (member->dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
803 member->dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
804 nextm->dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
805 nextm->dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
806 nextm->dsp->pcm_slot_tx == in dsp_cmx_hardware()
807 member->dsp->pcm_slot_rx && in dsp_cmx_hardware()
808 nextm->dsp->pcm_slot_rx == in dsp_cmx_hardware()
809 member->dsp->pcm_slot_tx && in dsp_cmx_hardware()
810 member->dsp->pcm_slot_tx != in dsp_cmx_hardware()
811 member->dsp->pcm_slot_rx && in dsp_cmx_hardware()
812 member->dsp->pcm_bank_tx == 0 && in dsp_cmx_hardware()
813 member->dsp->pcm_bank_rx == 0 && in dsp_cmx_hardware()
814 nextm->dsp->pcm_bank_tx == 0 && in dsp_cmx_hardware()
815 nextm->dsp->pcm_bank_rx == 0) { in dsp_cmx_hardware()
820 "slot %d (TX) %d (RX) on same chip " in dsp_cmx_hardware()
822 member->dsp->name, in dsp_cmx_hardware()
823 nextm->dsp->name, in dsp_cmx_hardware()
824 member->dsp->pcm_slot_tx, in dsp_cmx_hardware()
825 member->dsp->pcm_slot_rx); in dsp_cmx_hardware()
826 conf->hardware = 1; in dsp_cmx_hardware()
827 conf->software = tx_data; in dsp_cmx_hardware()
833 if (dsp != member->dsp && in dsp_cmx_hardware()
834 dsp != nextm->dsp && in dsp_cmx_hardware()
835 member->dsp->features.pcm_id == in dsp_cmx_hardware()
836 dsp->features.pcm_id) { in dsp_cmx_hardware()
837 if (dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
838 dsp->pcm_slot_rx < in dsp_cmx_hardware()
840 freeslots[dsp->pcm_slot_rx] = 0; in dsp_cmx_hardware()
841 if (dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
842 dsp->pcm_slot_tx < in dsp_cmx_hardware()
844 freeslots[dsp->pcm_slot_tx] = 0; in dsp_cmx_hardware()
848 ii = member->dsp->features.pcm_slots; in dsp_cmx_hardware()
859 member->dsp->name, in dsp_cmx_hardware()
860 nextm->dsp->name); in dsp_cmx_hardware()
876 member->dsp->name, in dsp_cmx_hardware()
877 nextm->dsp->name); in dsp_cmx_hardware()
882 member->dsp->pcm_slot_tx = i1; in dsp_cmx_hardware()
883 member->dsp->pcm_slot_rx = i2; in dsp_cmx_hardware()
884 nextm->dsp->pcm_slot_tx = i2; in dsp_cmx_hardware()
885 nextm->dsp->pcm_slot_rx = i1; in dsp_cmx_hardware()
886 member->dsp->pcm_bank_rx = 0; in dsp_cmx_hardware()
887 member->dsp->pcm_bank_tx = 0; in dsp_cmx_hardware()
888 nextm->dsp->pcm_bank_rx = 0; in dsp_cmx_hardware()
889 nextm->dsp->pcm_bank_tx = 0; in dsp_cmx_hardware()
893 "(TX) %d (RX) on same chip or one bank " in dsp_cmx_hardware()
896 member->dsp->name, in dsp_cmx_hardware()
897 nextm->dsp->name, in dsp_cmx_hardware()
898 member->dsp->pcm_slot_tx, in dsp_cmx_hardware()
899 member->dsp->pcm_slot_rx); in dsp_cmx_hardware()
900 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, in dsp_cmx_hardware()
901 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, in dsp_cmx_hardware()
902 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); in dsp_cmx_hardware()
903 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, in dsp_cmx_hardware()
904 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, in dsp_cmx_hardware()
905 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); in dsp_cmx_hardware()
906 conf->hardware = 1; in dsp_cmx_hardware()
907 conf->software = tx_data; in dsp_cmx_hardware()
924 __func__, conf->id); in dsp_cmx_hardware()
932 conf->hardware = 1; in dsp_cmx_hardware()
933 conf->software = tx_data; in dsp_cmx_hardware()
942 list_for_each_entry(member, &conf->mlist, list) { in dsp_cmx_hardware()
945 if (!member->dsp->features.hfc_conf) in dsp_cmx_hardware()
948 if (member->dsp->hdlc) in dsp_cmx_hardware()
951 if (member->dsp->hfc_conf == current_conf) in dsp_cmx_hardware()
961 dsp != member->dsp && in dsp_cmx_hardware()
963 member->dsp->features.pcm_id == in dsp_cmx_hardware()
964 dsp->features.pcm_id) { in dsp_cmx_hardware()
966 if (dsp->pcm_slot_tx >= 0 && in dsp_cmx_hardware()
967 dsp->pcm_slot_tx < in dsp_cmx_hardware()
969 freeslots[dsp->pcm_slot_tx] = 0; in dsp_cmx_hardware()
970 if (dsp->pcm_slot_rx >= 0 && in dsp_cmx_hardware()
971 dsp->pcm_slot_rx < in dsp_cmx_hardware()
973 freeslots[dsp->pcm_slot_rx] = 0; in dsp_cmx_hardware()
977 ii = member->dsp->features.pcm_slots; in dsp_cmx_hardware()
989 __func__, conf->id); in dsp_cmx_hardware()
996 member->dsp->name, current_conf, i); in dsp_cmx_hardware()
997 /* assign free slot & set PCM & join conf */ in dsp_cmx_hardware()
998 member->dsp->pcm_slot_tx = i; in dsp_cmx_hardware()
999 member->dsp->pcm_slot_rx = i; in dsp_cmx_hardware()
1000 member->dsp->pcm_bank_tx = 2; /* loop */ in dsp_cmx_hardware()
1001 member->dsp->pcm_bank_rx = 2; in dsp_cmx_hardware()
1002 member->dsp->hfc_conf = current_conf; in dsp_cmx_hardware()
1003 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, in dsp_cmx_hardware()
1005 dsp_cmx_hw_message(member->dsp, in dsp_cmx_hardware()
1008 conf->hardware = 1; in dsp_cmx_hardware()
1009 conf->software = tx_data; in dsp_cmx_hardware()
1019 if (dsp->features.hfc_id == same_hfc && in dsp_cmx_hardware()
1021 dsp->hfc_conf >= 0 && in dsp_cmx_hardware()
1023 dsp->hfc_conf < 8) in dsp_cmx_hardware()
1024 freeunits[dsp->hfc_conf] = 0; in dsp_cmx_hardware()
1039 __func__, conf->id); in dsp_cmx_hardware()
1056 struct dsp_conf *conf; in dsp_cmx_conf() local
1060 if (dsp->conf_id == conf_id) in dsp_cmx_conf()
1063 /* first remove us from current conf */ in dsp_cmx_conf()
1064 if (dsp->conf_id) { in dsp_cmx_conf()
1067 dsp->conf->id); in dsp_cmx_conf()
1068 /* remove us from conf */ in dsp_cmx_conf()
1069 conf = dsp->conf; in dsp_cmx_conf()
1073 dsp->conf_id = 0; in dsp_cmx_conf()
1078 /* conf now empty? */ in dsp_cmx_conf()
1079 if (list_empty(&conf->mlist)) { in dsp_cmx_conf()
1083 err = dsp_cmx_del_conf(conf); in dsp_cmx_conf()
1087 /* update members left on conf */ in dsp_cmx_conf()
1088 dsp_cmx_hardware(conf, NULL); in dsp_cmx_conf()
1096 /* now add us to conf */ in dsp_cmx_conf()
1100 conf = dsp_cmx_search_conf(conf_id); in dsp_cmx_conf()
1101 if (!conf) { in dsp_cmx_conf()
1106 conf = dsp_cmx_new_conf(conf_id); in dsp_cmx_conf()
1107 if (!conf) in dsp_cmx_conf()
1108 return -EINVAL; in dsp_cmx_conf()
1109 } else if (!list_empty(&conf->mlist)) { in dsp_cmx_conf()
1110 member = list_entry(conf->mlist.next, struct dsp_conf_member, in dsp_cmx_conf()
1112 if (dsp->hdlc && !member->dsp->hdlc) { in dsp_cmx_conf()
1116 return -EINVAL; in dsp_cmx_conf()
1118 if (!dsp->hdlc && member->dsp->hdlc) { in dsp_cmx_conf()
1122 return -EINVAL; in dsp_cmx_conf()
1126 err = dsp_cmx_add_conf_member(dsp, conf); in dsp_cmx_conf()
1129 dsp->conf_id = conf_id; in dsp_cmx_conf()
1132 if (list_empty(&conf->mlist)) { in dsp_cmx_conf()
1141 /* update members on conf */ in dsp_cmx_conf()
1142 dsp_cmx_hardware(conf, NULL); in dsp_cmx_conf()
1152 char bar[] = "--------------------------------------------------|"; in showdelay()
1162 printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay, in showdelay()
1163 sdelay > 50 ? "..." : bar + 50 - sdelay); in showdelay()
1174 int len = skb->len; in dsp_cmx_receive()
1192 * initialize pointers if not already - in dsp_cmx_receive()
1195 if (dsp->rx_init) { in dsp_cmx_receive()
1196 dsp->rx_init = 0; in dsp_cmx_receive()
1197 if (dsp->features.unordered) { in dsp_cmx_receive()
1198 dsp->rx_R = (hh->id & CMX_BUFF_MASK); in dsp_cmx_receive()
1199 if (dsp->cmx_delay) in dsp_cmx_receive()
1200 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) in dsp_cmx_receive()
1203 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) in dsp_cmx_receive()
1206 dsp->rx_R = 0; in dsp_cmx_receive()
1207 if (dsp->cmx_delay) in dsp_cmx_receive()
1208 dsp->rx_W = dsp->cmx_delay; in dsp_cmx_receive()
1210 dsp->rx_W = dsp_poll >> 1; in dsp_cmx_receive()
1214 if (dsp->features.unordered) { in dsp_cmx_receive()
1215 dsp->rx_W = (hh->id & CMX_BUFF_MASK); in dsp_cmx_receive()
1216 /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */ in dsp_cmx_receive()
1222 if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) { in dsp_cmx_receive()
1227 "(inst %s)\n", (u_long)dsp, dsp->name); in dsp_cmx_receive()
1228 /* flush rx buffer and set delay to dsp_poll / 2 */ in dsp_cmx_receive()
1229 if (dsp->features.unordered) { in dsp_cmx_receive()
1230 dsp->rx_R = (hh->id & CMX_BUFF_MASK); in dsp_cmx_receive()
1231 if (dsp->cmx_delay) in dsp_cmx_receive()
1232 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) in dsp_cmx_receive()
1235 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) in dsp_cmx_receive()
1238 dsp->rx_R = 0; in dsp_cmx_receive()
1239 if (dsp->cmx_delay) in dsp_cmx_receive()
1240 dsp->rx_W = dsp->cmx_delay; in dsp_cmx_receive()
1242 dsp->rx_W = dsp_poll >> 1; in dsp_cmx_receive()
1244 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); in dsp_cmx_receive()
1247 if (dsp->cmx_delay) in dsp_cmx_receive()
1248 if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >= in dsp_cmx_receive()
1249 (dsp->cmx_delay << 1)) { in dsp_cmx_receive()
1255 (u_long)dsp, dsp->name); in dsp_cmx_receive()
1257 if (dsp->features.unordered) { in dsp_cmx_receive()
1258 dsp->rx_R = (hh->id & CMX_BUFF_MASK); in dsp_cmx_receive()
1259 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) in dsp_cmx_receive()
1262 dsp->rx_R = 0; in dsp_cmx_receive()
1263 dsp->rx_W = dsp->cmx_delay; in dsp_cmx_receive()
1265 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); in dsp_cmx_receive()
1272 (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name); in dsp_cmx_receive()
1276 p = skb->data; in dsp_cmx_receive()
1277 d = dsp->rx_buff; in dsp_cmx_receive()
1278 w = dsp->rx_W; in dsp_cmx_receive()
1286 /* increase write-pointer */ in dsp_cmx_receive()
1287 dsp->rx_W = ((dsp->rx_W + len) & CMX_BUFF_MASK); in dsp_cmx_receive()
1289 showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK); in dsp_cmx_receive()
1300 struct dsp_conf *conf = dsp->conf; local
1311 if (!dsp->b_active) { /* if not active */
1312 dsp->last_tx = 0;
1315 if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
1316 dsp->echo.hardware) && /* OR hardware echo */
1317 dsp->tx_R == dsp->tx_W && /* AND no tx-data */
1318 !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
1319 if (!dsp->tx_data) { /* no tx_data for user space required */
1320 dsp->last_tx = 0;
1323 if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
1325 if (dsp->echo.software && dsp->echo.hardware)
1331 "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
1332 members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
1336 if (dsp->cmx_delay && !dsp->last_tx) {
1351 hh->prim = PH_DATA_REQ;
1352 hh->id = 0;
1353 dsp->last_tx = 1;
1357 p = dsp->tx_buff; /* transmit data */
1358 q = dsp->rx_buff; /* received data */
1360 t = dsp->tx_R; /* tx-pointers */
1361 tt = dsp->tx_W;
1362 r = dsp->rx_R; /* rx-pointers */
1371 /* PROCESS TONES/TX-DATA ONLY */
1372 if (dsp->tone.tone && dsp->tone.software) {
1373 /* -> copy tone */
1375 dsp->tx_R = 0; /* clear tx buffer */
1376 dsp->tx_W = 0;
1379 /* if we have tx-data but do not use mixing */
1380 if (!dsp->tx_mix && t != tt) {
1381 /* -> send tx-data and continue when not enough */
1383 sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
1396 dsp->tx_R = t;
1407 /* PROCESS DATA (one member / no conf) */
1408 if (!conf || members <= 1) {
1409 /* -> if echo is NOT enabled */
1410 if (!dsp->echo.software) {
1411 /* -> send tx-data if available or use 0-volume */
1419 printk(KERN_DEBUG "%s: RX empty\n",
1421 memset(d, dsp_silence, (rr - r) & CMX_BUFF_MASK);
1423 /* -> if echo is enabled */
1426 * -> mix tx-data with echo if available,
1439 dsp->tx_R = t;
1449 other = (list_entry(conf->mlist.next,
1450 struct dsp_conf_member, list))->dsp;
1452 other = (list_entry(conf->mlist.prev,
1453 struct dsp_conf_member, list))->dsp;
1454 o_q = other->rx_buff; /* received data */
1455 o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
1456 /* end of rx-pointer */
1457 o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
1458 /* start rx-pointer at current read position*/
1459 /* -> if echo is NOT enabled */
1460 if (!dsp->echo.software) {
1462 * -> copy other member's rx-data,
1463 * if tx-data is available, mix
1474 /* -> if echo is enabled */
1477 * -> mix other member's rx-data with echo,
1478 * if tx-data is available, mix
1484 if (sample < -32768)
1485 sample = -32768;
1489 /* tx-data + rx_data + echo */
1500 dsp->tx_R = t;
1504 /* -> if echo is NOT enabled */
1505 if (!dsp->echo.software) {
1507 * -> subtract rx-data from conf-data,
1508 * if tx-data is available, mix
1511 sample = dsp_audio_law_to_s32[p[t]] + *c++ -
1513 if (sample < -32768)
1514 sample = -32768;
1518 /* conf-rx+tx */
1523 sample = *c++ - dsp_audio_law_to_s32[q[r]];
1524 if (sample < -32768)
1525 sample = -32768;
1529 /* conf-rx */
1532 /* -> if echo is enabled */
1535 * -> encode conf-data, if tx-data
1540 if (sample < -32768)
1541 sample = -32768;
1545 /* conf(echo)+tx */
1551 if (sample < -32768)
1552 sample = -32768;
1556 /* conf(echo) */
1560 dsp->tx_R = t;
1565 * send tx-data if enabled - don't filter,
1568 if (dsp->tx_data) {
1570 hh->prim = DL_DATA_REQ;
1571 hh->id = 0;
1573 skb_queue_tail(&dsp->sendq, nskb);
1574 schedule_work(&dsp->workq);
1585 thh->prim = DL_DATA_REQ;
1586 thh->id = 0;
1587 skb_put_data(txskb, nskb->data + preload, len);
1589 skb_queue_tail(&dsp->sendq, txskb);
1596 if (dsp->tx_volume)
1597 dsp_change_volume(nskb, dsp->tx_volume);
1599 if (dsp->pipeline.inuse)
1600 dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
1601 nskb->len);
1603 if (dsp->bf_enable)
1604 dsp_bf_encrypt(dsp, nskb->data, nskb->len);
1606 skb_queue_tail(&dsp->sendq, nskb);
1607 schedule_work(&dsp->workq);
1619 struct dsp_conf *conf; local
1640 length = count - dsp_count;
1652 jittercount -= 8000;
1658 if (dsp->hdlc)
1660 conf = dsp->conf;
1663 if (conf) {
1664 members = list_count_nodes(&conf->mlist);
1666 if (conf->software && members > 1)
1668 if (conf->software && members > 2)
1679 * potential null-pointer-bug
1685 list_for_each_entry(conf, &conf_ilist, list) {
1687 members = list_count_nodes(&conf->mlist);
1689 if (conf->software && members > 1) {
1691 if (conf->software && members > 2) {
1693 /* check for hdlc conf */
1694 member = list_entry(conf->mlist.next,
1696 if (member->dsp->hdlc)
1700 list_for_each_entry(member, &conf->mlist, list) {
1701 dsp = member->dsp;
1704 q = dsp->rx_buff;
1705 r = dsp->rx_R;
1715 list_for_each_entry(member, &conf->mlist, list) {
1717 dsp_cmx_send_member(member->dsp, length,
1723 /* delete rx-data, increment buffers, change pointers */
1725 if (dsp->hdlc)
1727 p = dsp->rx_buff;
1728 q = dsp->tx_buff;
1729 r = dsp->rx_R;
1731 if (!dsp->rx_is_off) {
1733 /* delete rx-data */
1738 /* increment rx-buffer pointer */
1739 dsp->rx_R = r; /* write incremented read pointer */
1743 delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
1747 if (delay < dsp->rx_delay[0])
1748 dsp->rx_delay[0] = delay;
1750 delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
1754 if (delay < dsp->tx_delay[0])
1755 dsp->tx_delay[0] = delay;
1758 delay = dsp->rx_delay[0];
1761 if (delay > dsp->rx_delay[i])
1762 delay = dsp->rx_delay[i];
1770 if (delay > dsp_poll && !dsp->cmx_delay) {
1776 dsp->name);
1777 r = dsp->rx_R;
1778 rr = (r + delay - (dsp_poll >> 1))
1780 /* delete rx-data */
1785 /* increment rx-buffer pointer */
1786 dsp->rx_R = r;
1790 delay = dsp->tx_delay[0];
1793 if (delay > dsp->tx_delay[i])
1794 delay = dsp->tx_delay[i];
1801 if (delay > dsp_poll && dsp->tx_dejitter) {
1807 dsp->name);
1808 r = dsp->tx_R;
1809 rr = (r + delay - (dsp_poll >> 1))
1811 /* delete tx-data */
1816 /* increment rx-buffer pointer */
1817 dsp->tx_R = r;
1821 i = MAX_SECONDS_JITTER_CHECK - 1;
1823 dsp->rx_delay[i] = dsp->rx_delay[i - 1];
1824 dsp->tx_delay[i] = dsp->tx_delay[i - 1];
1825 i--;
1827 dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1828 dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1833 if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
1853 int space; /* todo: , l = skb->len; */
1859 w = dsp->tx_W;
1860 ww = dsp->tx_R;
1861 p = dsp->tx_buff;
1862 d = skb->data;
1863 space = (ww - w - 1) & CMX_BUFF_MASK;
1864 /* write-pointer should not overrun nor reach read pointer */
1865 if (space < skb->len) {
1867 ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
1869 printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
1871 skb->len, w, ww);
1874 ww = (w + skb->len) & CMX_BUFF_MASK;
1875 dsp->tx_W = ww;
1879 "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
1880 (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
1883 /* copy transmit data to tx-buffer */
1885 sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
1912 if (!dsp->b_active)
1916 if (skb->len < 1)
1919 /* no conf */
1920 if (!dsp->conf) {
1922 if (dsp->echo.software) {
1926 hh->prim = PH_DATA_REQ;
1927 hh->id = 0;
1928 skb_queue_tail(&dsp->sendq, nskb);
1929 schedule_work(&dsp->workq);
1935 if (dsp->conf->hardware)
1937 list_for_each_entry(member, &dsp->conf->mlist, list) {
1938 if (dsp->echo.software || member->dsp != dsp) {
1942 hh->prim = PH_DATA_REQ;
1943 hh->id = 0;
1944 skb_queue_tail(&member->dsp->sendq, nskb);
1945 schedule_work(&member->dsp->workq);