/*
 * Author       Andreas Eversberg (jolly@eversberg.eu)
 * Based on source code structure by
 *		Karsten Keil (keil@isdn4linux.de)
 *
 *		This file is (c) under GNU PUBLIC LICENSE
 *		For changes and modifications please read
 *		../../../Documentation/isdn/mISDN.cert
 *
 * Thanks to    Karsten Keil (great drivers)
 *              Cologne Chip (great chips)
 *
 * This module does:
 *		Real-time tone generation
 *		DTMF detection
 *		Real-time cross-connection and conferrence
 *		Compensate jitter due to system load and hardware fault.
 *		All features are done in kernel space and will be realized
 *		using hardware, if available and supported by chip set.
 *		Blowfish encryption/decryption
 */

/* STRUCTURE:
 *
 * The dsp module provides layer 2 for b-channels (64kbit). It provides
 * transparent audio forwarding with special digital signal processing:
 *
 * - (1) generation of tones
 * - (2) detection of dtmf tones
 * - (3) crossconnecting and conferences (clocking)
 * - (4) echo generation for delay test
 * - (5) volume control
 * - (6) disable receive data
 * - (7) pipeline
 * - (8) encryption/decryption
 *
 * Look:
 *             TX            RX
 *         ------upper layer------
 *             |             ^
 *             |             |(6)
 *             v             |
 *       +-----+-------------+-----+
 *       |(3)(4)                   |
 *       |           CMX           |
 *       |                         |
 *       |           +-------------+
 *       |           |       ^
 *       |           |       |
 *       |+---------+|  +----+----+
 *       ||(1)      ||  |(2)      |
 *       ||         ||  |         |
 *       ||  Tones  ||  |  DTMF   |
 *       ||         ||  |         |
 *       ||         ||  |         |
 *       |+----+----+|  +----+----+
 *       +-----+-----+       ^
 *             |             |
 *             v             |
 *        +----+----+   +----+----+
 *        |(5)      |   |(5)      |
 *        |         |   |         |
 *        |TX Volume|   |RX Volume|
 *        |         |   |         |
 *        |         |   |         |
 *        +----+----+   +----+----+
 *             |             ^
 *             |             |
 *             v             |
 *        +----+-------------+----+
 *        |(7)                    |
 *        |                       |
 *        |  Pipeline Processing  |
 *        |                       |
 *        |                       |
 *        +----+-------------+----+
 *             |             ^
 *             |             |
 *             v             |
 *        +----+----+   +----+----+
 *        |(8)      |   |(8)      |
 *        |         |   |         |
 *        | Encrypt |   | Decrypt |
 *        |         |   |         |
 *        |         |   |         |
 *        +----+----+   +----+----+
 *             |             ^
 *             |             |
 *             v             |
 *         ------card  layer------
 *             TX            RX
 *
 * Above you can see the logical data flow. If software is used to do the
 * process, it is actually the real data flow. If hardware is used, data
 * may not flow, but hardware commands to the card, to provide the data flow
 * as shown.
 *
 * NOTE: The channel must be activated in order to make dsp work, even if
 * no data flow to the upper layer is intended. Activation can be done
 * after and before controlling the setting using PH_CONTROL requests.
 *
 * DTMF: Will be detected by hardware if possible. It is done before CMX
 * processing.
 *
 * Tones: Will be generated via software if endless looped audio fifos are
 * not supported by hardware. Tones will override all data from CMX.
 * It is not required to join a conference to use tones at any time.
 *
 * CMX: Is transparent when not used. When it is used, it will do
 * crossconnections and conferences via software if not possible through
 * hardware. If hardware capability is available, hardware is used.
 *
 * Echo: Is generated by CMX and is used to check performance of hard and
 * software CMX.
 *
 * The CMX has special functions for conferences with one, two and more
 * members. It will allow different types of data flow. Receive and transmit
 * data to/form upper layer may be swithed on/off individually without losing
 * features of CMX, Tones and DTMF.
 *
 * Echo Cancellation: Sometimes we like to cancel echo from the interface.
 * Note that a VoIP call may not have echo caused by the IP phone. The echo
 * is generated by the telephone line connected to it. Because the delay
 * is high, it becomes an echo. RESULT: Echo Cachelation is required if
 * both echo AND delay is applied to an interface.
 * Remember that software CMX always generates a more or less delay.
 *
 * If all used features can be realized in hardware, and if transmit and/or
 * receive data ist disabled, the card may not send/receive any data at all.
 * Not receiving is useful if only announcements are played. Not sending is
 * useful if an answering machine records audio. Not sending and receiving is
 * useful during most states of the call. If supported by hardware, tones
 * will be played without cpu load. Small PBXs and NT-Mode applications will
 * not need expensive hardware when processing calls.
 *
 *
 * LOCKING:
 *
 * When data is received from upper or lower layer (card), the complete dsp
 * module is locked by a global lock.  This lock MUST lock irq, because it
 * must lock timer events by DSP poll timer.
 * When data is ready to be transmitted down, the data is queued and sent
 * outside lock and timer event.
 * PH_CONTROL must not change any settings, join or split conference members
 * during process of data.
 *
 * HDLC:
 *
 * It works quite the same as transparent, except that HDLC data is forwarded
 * to all other conference members if no hardware bridging is possible.
 * Send data will be writte to sendq. Sendq will be sent if confirm is received.
 * Conference cannot join, if one member is not hdlc.
 *
 */

#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/mISDNif.h>
#include <linux/mISDNdsp.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include "core.h"
#include "dsp.h"

static const char *mISDN_dsp_revision = "2.0";

static int debug;
static int options;
static int poll;
static int dtmfthreshold = 100;

MODULE_AUTHOR("Andreas Eversberg");
module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(options, uint, S_IRUGO | S_IWUSR);
module_param(poll, uint, S_IRUGO | S_IWUSR);
module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR);
MODULE_LICENSE("GPL");

/*int spinnest = 0;*/

spinlock_t dsp_lock; /* global dsp lock */
struct list_head dsp_ilist;
struct list_head conf_ilist;
int dsp_debug;
int dsp_options;
int dsp_poll, dsp_tics;

/* check if rx may be turned off or must be turned on */
static void
dsp_rx_off_member(struct dsp *dsp)
{
	struct mISDN_ctrl_req	cq;
	int rx_off = 1;

	memset(&cq, 0, sizeof(cq));

	if (!dsp->features_rx_off)
		return;

	/* not disabled */
	if (!dsp->rx_disabled)
		rx_off = 0;
	/* software dtmf */
	else if (dsp->dtmf.software)
		rx_off = 0;
	/* echo in software */
	else if (dsp->echo.software)
		rx_off = 0;
	/* bridge in software */
	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;

	if (!dsp->ch.peer) {
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: no peer, no rx_off\n",
			       __func__);
		return;
	}
	cq.op = MISDN_CTRL_RX_OFF;
	cq.p1 = rx_off;
	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
		printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
		       __func__);
		return;
	}
	dsp->rx_is_off = rx_off;
	if (dsp_debug & DEBUG_DSP_CORE)
		printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
		       __func__, dsp->name, rx_off);
}
static void
dsp_rx_off(struct dsp *dsp)
{
	struct dsp_conf_member	*member;

	if (dsp_options & DSP_OPT_NOHARDWARE)
		return;

	/* no conf */
	if (!dsp->conf) {
		dsp_rx_off_member(dsp);
		return;
	}
	/* check all members in conf */
	list_for_each_entry(member, &dsp->conf->mlist, list) {
		dsp_rx_off_member(member->dsp);
	}
}

/* enable "fill empty" feature */
static void
dsp_fill_empty(struct dsp *dsp)
{
	struct mISDN_ctrl_req	cq;

	memset(&cq, 0, sizeof(cq));

	if (!dsp->ch.peer) {
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
			       __func__);
		return;
	}
	cq.op = MISDN_CTRL_FILL_EMPTY;
	cq.p1 = 1;
	cq.p2 = dsp_silence;
	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
		       __func__);
		return;
	}
	if (dsp_debug & DEBUG_DSP_CORE)
		printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
		       __func__, dsp->name);
}

static int
dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
{
	struct sk_buff	*nskb;
	int ret = 0;
	int cont;
	u8 *data;
	int len;

	if (skb->len < sizeof(int)) {
		printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
		return -EINVAL;
	}
	cont = *((int *)skb->data);
	len = skb->len - sizeof(int);
	data = skb->data + sizeof(int);

	switch (cont) {
	case DTMF_TONE_START: /* turn on DTMF */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: start dtmf\n", __func__);
		if (len == sizeof(int)) {
			if (dsp_debug & DEBUG_DSP_CORE)
				printk(KERN_NOTICE "changing DTMF Threshold "
				       "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;
	case DSP_CONF_JOIN: /* join / update conference */
		if (len < sizeof(int)) {
			ret = -EINVAL;
			break;
		}
		if (*((u32 *)data) == 0)
			goto conf_split;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: join conference %d\n",
			       __func__, *((u32 *)data));
		ret = dsp_cmx_conf(dsp, *((u32 *)data));
		/* dsp_cmx_hardware will also be called here */
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_CONF_SPLIT: /* remove from conference */
	conf_split:
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: release conference\n", __func__);
		ret = dsp_cmx_conf(dsp, 0);
		/* dsp_cmx_hardware will also be called here */
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		dsp_rx_off(dsp);
		break;
	case DSP_TONE_PATT_ON: /* play tone */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len < sizeof(int)) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
			       __func__, *((int *)skb->data));
		ret = dsp_tone(dsp, *((int *)data));
		if (!ret) {
			dsp_cmx_hardware(dsp->conf, dsp);
			dsp_rx_off(dsp);
		}
		if (!dsp->tone.tone)
			goto tone_off;
		break;
	case DSP_TONE_PATT_OFF: /* stop tone */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: turn tone off\n", __func__);
		dsp_tone(dsp, 0);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		/* reset tx buffers (user space data) */
	tone_off:
		dsp->rx_W = 0;
		dsp->rx_R = 0;
		break;
	case DSP_VOL_CHANGE_TX: /* change volume */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len < sizeof(int)) {
			ret = -EINVAL;
			break;
		}
		dsp->tx_volume = *((int *)data);
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: change tx vol to %d\n",
			       __func__, dsp->tx_volume);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_dtmf_hardware(dsp);
		dsp_rx_off(dsp);
		break;
	case DSP_VOL_CHANGE_RX: /* change volume */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len < sizeof(int)) {
			ret = -EINVAL;
			break;
		}
		dsp->rx_volume = *((int *)data);
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: change rx vol to %d\n",
			       __func__, dsp->tx_volume);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_dtmf_hardware(dsp);
		dsp_rx_off(dsp);
		break;
	case DSP_ECHO_ON: /* enable 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);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_ECHO_OFF: /* disable echo */
		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);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_RECEIVE_ON: /* enable receive to user space */
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: enable receive to user "
			       "space\n", __func__);
		dsp->rx_disabled = 0;
		dsp_rx_off(dsp);
		break;
	case DSP_RECEIVE_OFF: /* disable receive to user space */
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: disable receive to "
			       "user space\n", __func__);
		dsp->rx_disabled = 1;
		dsp_rx_off(dsp);
		break;
	case DSP_MIX_ON: /* enable mixing of tx data */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: enable mixing of "
			       "tx-data with conf mebers\n", __func__);
		dsp->tx_mix = 1;
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_MIX_OFF: /* disable mixing of tx data */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: disable mixing of "
			       "tx-data with conf mebers\n", __func__);
		dsp->tx_mix = 0;
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_TXDATA_ON: /* enable txdata */
		dsp->tx_data = 1;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: enable tx-data\n", __func__);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_TXDATA_OFF: /* disable txdata */
		dsp->tx_data = 0;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: disable tx-data\n", __func__);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		if (dsp_debug & DEBUG_DSP_CMX)
			dsp_cmx_debug(dsp);
		break;
	case DSP_DELAY: /* use delay algorithm instead of dynamic
			   jitter algorithm */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len < sizeof(int)) {
			ret = -EINVAL;
			break;
		}
		dsp->cmx_delay = (*((int *)data)) << 3;
		/* milliseconds to samples */
		if (dsp->cmx_delay >= (CMX_BUFF_HALF >> 1))
			/* clip to half of maximum usable buffer
			   (half of half buffer) */
			dsp->cmx_delay = (CMX_BUFF_HALF >> 1) - 1;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: use delay algorithm to "
			       "compensate jitter (%d samples)\n",
			       __func__, dsp->cmx_delay);
		break;
	case DSP_JITTER: /* use dynamic jitter algorithm instead of
			    delay algorithm */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		dsp->cmx_delay = 0;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: use jitter algorithm to "
			       "compensate jitter\n", __func__);
		break;
	case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		dsp->tx_dejitter = 1;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: use dejitter on TX "
			       "buffer\n", __func__);
		break;
	case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		dsp->tx_dejitter = 0;
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: use TX buffer without "
			       "dejittering\n", __func__);
		break;
	case DSP_PIPELINE_CFG:
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len > 0 && ((char *)data)[len - 1]) {
			printk(KERN_DEBUG "%s: pipeline config string "
			       "is not NULL terminated!\n", __func__);
			ret = -EINVAL;
		} else {
			dsp->pipeline.inuse = 1;
			dsp_cmx_hardware(dsp->conf, dsp);
			ret = dsp_pipeline_build(&dsp->pipeline,
						 len > 0 ? data : NULL);
			dsp_cmx_hardware(dsp->conf, dsp);
			dsp_rx_off(dsp);
		}
		break;
	case DSP_BF_ENABLE_KEY: /* turn blowfish on */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (len < 4 || len > 56) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: turn blowfish on (key "
			       "not shown)\n", __func__);
		ret = dsp_bf_init(dsp, (u8 *)data, len);
		/* set new cont */
		if (!ret)
			cont = DSP_BF_ACCEPT;
		else
			cont = DSP_BF_REJECT;
		/* send indication if it worked to set it */
		nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
					sizeof(int), &cont, GFP_ATOMIC);
		if (nskb) {
			if (dsp->up) {
				if (dsp->up->send(dsp->up, nskb))
					dev_kfree_skb(nskb);
			} else
				dev_kfree_skb(nskb);
		}
		if (!ret) {
			dsp_cmx_hardware(dsp->conf, dsp);
			dsp_dtmf_hardware(dsp);
			dsp_rx_off(dsp);
		}
		break;
	case DSP_BF_DISABLE: /* turn blowfish off */
		if (dsp->hdlc) {
			ret = -EINVAL;
			break;
		}
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: turn blowfish off\n", __func__);
		dsp_bf_cleanup(dsp);
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_dtmf_hardware(dsp);
		dsp_rx_off(dsp);
		break;
	default:
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
			       __func__, cont);
		ret = -EINVAL;
	}
	return ret;
}

static void
get_features(struct mISDNchannel *ch)
{
	struct dsp		*dsp = container_of(ch, struct dsp, ch);
	struct mISDN_ctrl_req	cq;

	if (!ch->peer) {
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: no peer, no features\n",
			       __func__);
		return;
	}
	memset(&cq, 0, sizeof(cq));
	cq.op = MISDN_CTRL_GETOP;
	if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
		       __func__);
		return;
	}
	if (cq.op & MISDN_CTRL_RX_OFF)
		dsp->features_rx_off = 1;
	if (cq.op & MISDN_CTRL_FILL_EMPTY)
		dsp->features_fill_empty = 1;
	if (dsp_options & DSP_OPT_NOHARDWARE)
		return;
	if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
		cq.op = MISDN_CTRL_HW_FEATURES;
		*((u_long *)&cq.p1) = (u_long)&dsp->features;
		if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
			printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
			       __func__);
		}
	} else
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: features not supported for %s\n",
			       __func__, dsp->name);
}

static int
dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
{
	struct dsp		*dsp = container_of(ch, struct dsp, ch);
	struct mISDNhead	*hh;
	int			ret = 0;
	u8			*digits = NULL;
	u_long			flags;

	hh = mISDN_HEAD_P(skb);
	switch (hh->prim) {
		/* FROM DOWN */
	case (PH_DATA_CNF):
		dsp->data_pending = 0;
		/* trigger next hdlc frame, if any */
		if (dsp->hdlc) {
			spin_lock_irqsave(&dsp_lock, flags);
			if (dsp->b_active)
				schedule_work(&dsp->workq);
			spin_unlock_irqrestore(&dsp_lock, flags);
		}
		break;
	case (PH_DATA_IND):
	case (DL_DATA_IND):
		if (skb->len < 1) {
			ret = -EINVAL;
			break;
		}
		if (dsp->rx_is_off) {
			if (dsp_debug & DEBUG_DSP_CORE)
				printk(KERN_DEBUG "%s: rx-data during rx_off"
				       " for %s\n",
				       __func__, dsp->name);
		}
		if (dsp->hdlc) {
			/* hdlc */
			spin_lock_irqsave(&dsp_lock, flags);
			dsp_cmx_hdlc(dsp, skb);
			spin_unlock_irqrestore(&dsp_lock, flags);
			if (dsp->rx_disabled) {
				/* if receive is not allowed */
				break;
			}
			hh->prim = DL_DATA_IND;
			if (dsp->up)
				return dsp->up->send(dsp->up, 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, 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);
		}
		/* 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);
				k = *digits | DTMF_TONE_VAL;
				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
							MISDN_ID_ANY, sizeof(int), &k,
							GFP_ATOMIC);
				if (nskb) {
					if (dsp->up) {
						if (dsp->up->send(
							    dsp->up, nskb))
							dev_kfree_skb(nskb);
					} else
						dev_kfree_skb(nskb);
				}
				digits++;
			}
		}
		if (dsp->rx_disabled) {
			/* if receive is not allowed */
			break;
		}
		hh->prim = DL_DATA_IND;
		if (dsp->up)
			return dsp->up->send(dsp->up, skb);
		break;
	case (PH_CONTROL_IND):
		if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
			printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
			       "received: %x (len %d) %s\n", __func__,
			       hh->id, skb->len, dsp->name);
		switch (hh->id) {
		case (DTMF_HFC_COEF): /* getting coefficients */
			if (!dsp->dtmf.hardware) {
				if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
					printk(KERN_DEBUG "%s: ignoring DTMF "
					       "coefficients from HFC\n",
					       __func__);
				break;
			}
			digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
							  skb->len, 2);
			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);
				k = *digits | DTMF_TONE_VAL;
				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
							MISDN_ID_ANY, sizeof(int), &k,
							GFP_ATOMIC);
				if (nskb) {
					if (dsp->up) {
						if (dsp->up->send(
							    dsp->up, nskb))
							dev_kfree_skb(nskb);
					} else
						dev_kfree_skb(nskb);
				}
				digits++;
			}
			break;
		case (HFC_VOL_CHANGE_TX): /* change volume */
			if (skb->len != sizeof(int)) {
				ret = -EINVAL;
				break;
			}
			spin_lock_irqsave(&dsp_lock, flags);
			dsp->tx_volume = *((int *)skb->data);
			if (dsp_debug & DEBUG_DSP_CORE)
				printk(KERN_DEBUG "%s: change tx volume to "
				       "%d\n", __func__, dsp->tx_volume);
			dsp_cmx_hardware(dsp->conf, dsp);
			dsp_dtmf_hardware(dsp);
			dsp_rx_off(dsp);
			spin_unlock_irqrestore(&dsp_lock, flags);
			break;
		default:
			if (dsp_debug & DEBUG_DSP_CORE)
				printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
				       "%s\n", __func__, hh->id, dsp->name);
			ret = -EINVAL;
		}
		break;
	case (PH_ACTIVATE_IND):
	case (PH_ACTIVATE_CNF):
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: b_channel is now active %s\n",
			       __func__, dsp->name);
		/* bchannel now active */
		spin_lock_irqsave(&dsp_lock, flags);
		dsp->b_active = 1;
		dsp->data_pending = 0;
		dsp->rx_init = 1;
		/* rx_W and rx_R will be adjusted on first frame */
		dsp->rx_W = 0;
		dsp->rx_R = 0;
		memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_dtmf_hardware(dsp);
		dsp_rx_off(dsp);
		spin_unlock_irqrestore(&dsp_lock, flags);
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: done with activation, sending "
			       "confirm to user space. %s\n", __func__,
			       dsp->name);
		/* send activation to upper layer */
		hh->prim = DL_ESTABLISH_CNF;
		if (dsp->up)
			return dsp->up->send(dsp->up, skb);
		break;
	case (PH_DEACTIVATE_IND):
	case (PH_DEACTIVATE_CNF):
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
			       __func__, dsp->name);
		/* bchannel now inactive */
		spin_lock_irqsave(&dsp_lock, flags);
		dsp->b_active = 0;
		dsp->data_pending = 0;
		dsp_cmx_hardware(dsp->conf, dsp);
		dsp_rx_off(dsp);
		spin_unlock_irqrestore(&dsp_lock, flags);
		hh->prim = DL_RELEASE_CNF;
		if (dsp->up)
			return dsp->up->send(dsp->up, skb);
		break;
		/* FROM UP */
	case (DL_DATA_REQ):
	case (PH_DATA_REQ):
		if (skb->len < 1) {
			ret = -EINVAL;
			break;
		}
		if (dsp->hdlc) {
			/* hdlc */
			if (!dsp->b_active) {
				ret = -EIO;
				break;
			}
			hh->prim = PH_DATA_REQ;
			spin_lock_irqsave(&dsp_lock, flags);
			skb_queue_tail(&dsp->sendq, skb);
			schedule_work(&dsp->workq);
			spin_unlock_irqrestore(&dsp_lock, flags);
			return 0;
		}
		/* send data to tx-buffer (if no tone is played) */
		if (!dsp->tone.tone) {
			spin_lock_irqsave(&dsp_lock, flags);
			dsp_cmx_transmit(dsp, skb);
			spin_unlock_irqrestore(&dsp_lock, flags);
		}
		break;
	case (PH_CONTROL_REQ):
		spin_lock_irqsave(&dsp_lock, flags);
		ret = dsp_control_req(dsp, hh, skb);
		spin_unlock_irqrestore(&dsp_lock, flags);
		break;
	case (DL_ESTABLISH_REQ):
	case (PH_ACTIVATE_REQ):
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: activating b_channel %s\n",
			       __func__, dsp->name);
		if (dsp->dtmf.hardware || dsp->dtmf.software)
			dsp_dtmf_goertzel_init(dsp);
		get_features(ch);
		/* enable fill_empty feature */
		if (dsp->features_fill_empty)
			dsp_fill_empty(dsp);
		/* send ph_activate */
		hh->prim = PH_ACTIVATE_REQ;
		if (ch->peer)
			return ch->recv(ch->peer, skb);
		break;
	case (DL_RELEASE_REQ):
	case (PH_DEACTIVATE_REQ):
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: releasing b_channel %s\n",
			       __func__, dsp->name);
		spin_lock_irqsave(&dsp_lock, flags);
		dsp->tone.tone = 0;
		dsp->tone.hardware = 0;
		dsp->tone.software = 0;
		if (timer_pending(&dsp->tone.tl))
			del_timer(&dsp->tone.tl);
		if (dsp->conf)
			dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be
						 called here */
		skb_queue_purge(&dsp->sendq);
		spin_unlock_irqrestore(&dsp_lock, flags);
		hh->prim = PH_DEACTIVATE_REQ;
		if (ch->peer)
			return ch->recv(ch->peer, skb);
		break;
	default:
		if (dsp_debug & DEBUG_DSP_CORE)
			printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
			       __func__, hh->prim, dsp->name);
		ret = -EINVAL;
	}
	if (!ret)
		dev_kfree_skb(skb);
	return ret;
}

static int
dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
	struct dsp		*dsp = container_of(ch, struct dsp, ch);
	u_long		flags;
	int		err = 0;

	if (debug & DEBUG_DSP_CTRL)
		printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);

	switch (cmd) {
	case OPEN_CHANNEL:
		break;
	case CLOSE_CHANNEL:
		if (dsp->ch.peer)
			dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL);

		/* wait until workqueue has finished,
		 * must lock here, or we may hit send-process currently
		 * queueing. */
		spin_lock_irqsave(&dsp_lock, flags);
		dsp->b_active = 0;
		spin_unlock_irqrestore(&dsp_lock, flags);
		/* MUST not be locked, because it waits until queue is done. */
		cancel_work_sync(&dsp->workq);
		spin_lock_irqsave(&dsp_lock, flags);
		if (timer_pending(&dsp->tone.tl))
			del_timer(&dsp->tone.tl);
		skb_queue_purge(&dsp->sendq);
		if (dsp_debug & DEBUG_DSP_CTRL)
			printk(KERN_DEBUG "%s: releasing member %s\n",
			       __func__, dsp->name);
		dsp->b_active = 0;
		dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called
					 here */
		dsp_pipeline_destroy(&dsp->pipeline);

		if (dsp_debug & DEBUG_DSP_CTRL)
			printk(KERN_DEBUG "%s: remove & destroy object %s\n",
			       __func__, dsp->name);
		list_del(&dsp->list);
		spin_unlock_irqrestore(&dsp_lock, flags);

		if (dsp_debug & DEBUG_DSP_CTRL)
			printk(KERN_DEBUG "%s: dsp instance released\n",
			       __func__);
		vfree(dsp);
		module_put(THIS_MODULE);
		break;
	}
	return err;
}

static void
dsp_send_bh(struct work_struct *work)
{
	struct dsp *dsp = container_of(work, struct dsp, workq);
	struct sk_buff *skb;
	struct mISDNhead	*hh;

	if (dsp->hdlc && dsp->data_pending)
		return; /* wait until data has been acknowledged */

	/* send queued data */
	while ((skb = skb_dequeue(&dsp->sendq))) {
		/* in locked date, we must have still data in queue */
		if (dsp->data_pending) {
			if (dsp_debug & DEBUG_DSP_CORE)
				printk(KERN_DEBUG "%s: fifo full %s, this is "
				       "no bug!\n", __func__, dsp->name);
			/* flush transparent data, if not acked */
			dev_kfree_skb(skb);
			continue;
		}
		hh = mISDN_HEAD_P(skb);
		if (hh->prim == DL_DATA_REQ) {
			/* send packet up */
			if (dsp->up) {
				if (dsp->up->send(dsp->up, skb))
					dev_kfree_skb(skb);
			} else
				dev_kfree_skb(skb);
		} else {
			/* send packet down */
			if (dsp->ch.peer) {
				dsp->data_pending = 1;
				if (dsp->ch.recv(dsp->ch.peer, skb)) {
					dev_kfree_skb(skb);
					dsp->data_pending = 0;
				}
			} else
				dev_kfree_skb(skb);
		}
	}
}

static int
dspcreate(struct channel_req *crq)
{
	struct dsp		*ndsp;
	u_long		flags;

	if (crq->protocol != ISDN_P_B_L2DSP
	    && crq->protocol != ISDN_P_B_L2DSPHDLC)
		return -EPROTONOSUPPORT;
	ndsp = vzalloc(sizeof(struct dsp));
	if (!ndsp) {
		printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__);
		return -ENOMEM;
	}
	if (dsp_debug & DEBUG_DSP_CTRL)
		printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__);

	/* default enabled */
	INIT_WORK(&ndsp->workq, (void *)dsp_send_bh);
	skb_queue_head_init(&ndsp->sendq);
	ndsp->ch.send = dsp_function;
	ndsp->ch.ctrl = dsp_ctrl;
	ndsp->up = crq->ch;
	crq->ch = &ndsp->ch;
	if (crq->protocol == ISDN_P_B_L2DSP) {
		crq->protocol = ISDN_P_B_RAW;
		ndsp->hdlc = 0;
	} else {
		crq->protocol = ISDN_P_B_HDLC;
		ndsp->hdlc = 1;
	}
	if (!try_module_get(THIS_MODULE))
		printk(KERN_WARNING "%s:cannot get module\n",
		       __func__);

	sprintf(ndsp->name, "DSP_C%x(0x%p)",
		ndsp->up->st->dev->id + 1, ndsp);
	/* set frame size to start */
	ndsp->features.hfc_id = -1; /* current PCM id */
	ndsp->features.pcm_id = -1; /* current PCM id */
	ndsp->pcm_slot_rx = -1; /* current CPM slot */
	ndsp->pcm_slot_tx = -1;
	ndsp->pcm_bank_rx = -1;
	ndsp->pcm_bank_tx = -1;
	ndsp->hfc_conf = -1; /* current conference number */
	/* set tone timer */
	ndsp->tone.tl.function = (void *)dsp_tone_timeout;
	ndsp->tone.tl.data = (long) ndsp;
	init_timer(&ndsp->tone.tl);

	if (dtmfthreshold < 20 || dtmfthreshold > 500)
		dtmfthreshold = 200;
	ndsp->dtmf.treshold = dtmfthreshold * 10000;

	/* init pipeline append to list */
	spin_lock_irqsave(&dsp_lock, flags);
	dsp_pipeline_init(&ndsp->pipeline);
	list_add_tail(&ndsp->list, &dsp_ilist);
	spin_unlock_irqrestore(&dsp_lock, flags);

	return 0;
}


static struct Bprotocol DSP = {
	.Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
	| (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
	.name = "dsp",
	.create = dspcreate
};

static int __init dsp_init(void)
{
	int err;
	int tics;

	printk(KERN_INFO "DSP module %s\n", mISDN_dsp_revision);

	dsp_options = options;
	dsp_debug = debug;

	/* set packet size */
	dsp_poll = poll;
	if (dsp_poll) {
		if (dsp_poll > MAX_POLL) {
			printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
			       "maximum.\n", __func__, poll, MAX_POLL);
			err = -EINVAL;
			return err;
		}
		if (dsp_poll < 8) {
			printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
			       "minimum.\n", __func__, dsp_poll);
			err = -EINVAL;
			return err;
		}
		dsp_tics = poll * HZ / 8000;
		if (dsp_tics * 8000 != poll * HZ) {
			printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
			       "samples (0,125 ms). It is not a multiple of "
			       "%d HZ.\n", poll, HZ);
			err = -EINVAL;
			return err;
		}
	} else {
		poll = 8;
		while (poll <= MAX_POLL) {
			tics = (poll * HZ) / 8000;
			if (tics * 8000 == poll * HZ) {
				dsp_tics = tics;
				dsp_poll = poll;
				if (poll >= 64)
					break;
			}
			poll++;
		}
	}
	if (dsp_poll == 0) {
		printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
		       "clock that equals exactly the duration of 8-256 "
		       "samples. (Choose kernel clock speed like 100, 250, "
		       "300, 1000)\n");
		err = -EINVAL;
		return err;
	}
	printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
	       "%d jiffies.\n", dsp_poll, dsp_tics);

	spin_lock_init(&dsp_lock);
	INIT_LIST_HEAD(&dsp_ilist);
	INIT_LIST_HEAD(&conf_ilist);

	/* 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_audio_generate_s2law_table();
	dsp_audio_generate_seven();
	dsp_audio_generate_mix_table();
	if (dsp_options & DSP_OPT_ULAW)
		dsp_audio_generate_ulaw_samples();
	dsp_audio_generate_volume_changes();

	err = dsp_pipeline_module_init();
	if (err) {
		printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
		       "error(%d)\n", err);
		return err;
	}

	err = mISDN_register_Bprotocol(&DSP);
	if (err) {
		printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err);
		return err;
	}

	/* set sample timer */
	dsp_spl_tl.function = (void *)dsp_cmx_send;
	dsp_spl_tl.data = 0;
	init_timer(&dsp_spl_tl);
	dsp_spl_tl.expires = jiffies + dsp_tics;
	dsp_spl_jiffies = dsp_spl_tl.expires;
	add_timer(&dsp_spl_tl);

	return 0;
}


static void __exit dsp_cleanup(void)
{
	mISDN_unregister_Bprotocol(&DSP);

	del_timer_sync(&dsp_spl_tl);

	if (!list_empty(&dsp_ilist)) {
		printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
		       "empty.\n");
	}
	if (!list_empty(&conf_ilist)) {
		printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
		       "all memory freed.\n");
	}

	dsp_pipeline_module_exit();
}

module_init(dsp_init);
module_exit(dsp_cleanup);
