xref: /OK3568_Linux_fs/kernel/drivers/isdn/mISDN/dsp.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Audio support data for ISDN4Linux.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This software may be used and distributed according to the terms
7*4882a593Smuzhiyun  * of the GNU General Public License, incorporated herein by reference.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define DEBUG_DSP_CTRL		0x0001
12*4882a593Smuzhiyun #define DEBUG_DSP_CORE		0x0002
13*4882a593Smuzhiyun #define DEBUG_DSP_DTMF		0x0004
14*4882a593Smuzhiyun #define DEBUG_DSP_CMX		0x0010
15*4882a593Smuzhiyun #define DEBUG_DSP_TONE		0x0020
16*4882a593Smuzhiyun #define DEBUG_DSP_BLOWFISH	0x0040
17*4882a593Smuzhiyun #define DEBUG_DSP_DELAY		0x0100
18*4882a593Smuzhiyun #define DEBUG_DSP_CLOCK		0x0200
19*4882a593Smuzhiyun #define DEBUG_DSP_DTMFCOEFF	0x8000 /* heavy output */
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /* options may be:
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * bit 0 = use ulaw instead of alaw
24*4882a593Smuzhiyun  * bit 1 = enable hfc hardware acceleration for all channels
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  */
27*4882a593Smuzhiyun #define DSP_OPT_ULAW		(1 << 0)
28*4882a593Smuzhiyun #define DSP_OPT_NOHARDWARE	(1 << 1)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include <linux/timer.h>
31*4882a593Smuzhiyun #include <linux/workqueue.h>
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #include "dsp_ecdis.h"
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun extern int dsp_options;
36*4882a593Smuzhiyun extern int dsp_debug;
37*4882a593Smuzhiyun extern int dsp_poll;
38*4882a593Smuzhiyun extern int dsp_tics;
39*4882a593Smuzhiyun extern spinlock_t dsp_lock;
40*4882a593Smuzhiyun extern struct work_struct dsp_workq;
41*4882a593Smuzhiyun extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /***************
44*4882a593Smuzhiyun  * audio stuff *
45*4882a593Smuzhiyun  ***************/
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun extern s32 dsp_audio_alaw_to_s32[256];
48*4882a593Smuzhiyun extern s32 dsp_audio_ulaw_to_s32[256];
49*4882a593Smuzhiyun extern s32 *dsp_audio_law_to_s32;
50*4882a593Smuzhiyun extern u8 dsp_audio_s16_to_law[65536];
51*4882a593Smuzhiyun extern u8 dsp_audio_alaw_to_ulaw[256];
52*4882a593Smuzhiyun extern u8 dsp_audio_mix_law[65536];
53*4882a593Smuzhiyun extern u8 dsp_audio_seven2law[128];
54*4882a593Smuzhiyun extern u8 dsp_audio_law2seven[256];
55*4882a593Smuzhiyun extern void dsp_audio_generate_law_tables(void);
56*4882a593Smuzhiyun extern void dsp_audio_generate_s2law_table(void);
57*4882a593Smuzhiyun extern void dsp_audio_generate_seven(void);
58*4882a593Smuzhiyun extern void dsp_audio_generate_mix_table(void);
59*4882a593Smuzhiyun extern void dsp_audio_generate_ulaw_samples(void);
60*4882a593Smuzhiyun extern void dsp_audio_generate_volume_changes(void);
61*4882a593Smuzhiyun extern u8 dsp_silence;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /*************
65*4882a593Smuzhiyun  * cmx stuff *
66*4882a593Smuzhiyun  *************/
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define MAX_POLL	256	/* maximum number of send-chunks */
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #define CMX_BUFF_SIZE	0x8000	/* must be 2**n (0x1000 about 1/2 second) */
71*4882a593Smuzhiyun #define CMX_BUFF_HALF	0x4000	/* CMX_BUFF_SIZE / 2 */
72*4882a593Smuzhiyun #define CMX_BUFF_MASK	0x7fff	/* CMX_BUFF_SIZE - 1 */
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /* how many seconds will we check the lowest delay until the jitter buffer
75*4882a593Smuzhiyun    is reduced by that delay */
76*4882a593Smuzhiyun #define MAX_SECONDS_JITTER_CHECK 5
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun extern struct timer_list dsp_spl_tl;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /* the datatype need to match jiffies datatype */
81*4882a593Smuzhiyun extern unsigned long dsp_spl_jiffies;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* the structure of conferences:
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * each conference has a unique number, given by user space.
86*4882a593Smuzhiyun  * the conferences are linked in a chain.
87*4882a593Smuzhiyun  * each conference has members linked in a chain.
88*4882a593Smuzhiyun  * each dsplayer points to a member, each member points to a dsplayer.
89*4882a593Smuzhiyun  */
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* all members within a conference (this is linked 1:1 with the dsp) */
92*4882a593Smuzhiyun struct dsp;
93*4882a593Smuzhiyun struct dsp_conf_member {
94*4882a593Smuzhiyun 	struct list_head	list;
95*4882a593Smuzhiyun 	struct dsp		*dsp;
96*4882a593Smuzhiyun };
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun /* the list of all conferences */
99*4882a593Smuzhiyun struct dsp_conf {
100*4882a593Smuzhiyun 	struct list_head	list;
101*4882a593Smuzhiyun 	u32			id;
102*4882a593Smuzhiyun 	/* all cmx stacks with the same ID are
103*4882a593Smuzhiyun 	   connected */
104*4882a593Smuzhiyun 	struct list_head	mlist;
105*4882a593Smuzhiyun 	int			software; /* conf is processed by software */
106*4882a593Smuzhiyun 	int			hardware; /* conf is processed by hardware */
107*4882a593Smuzhiyun 	/* note: if both unset, has only one member */
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /**************
112*4882a593Smuzhiyun  * DTMF stuff *
113*4882a593Smuzhiyun  **************/
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define DSP_DTMF_NPOINTS 102
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun #define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
118*4882a593Smuzhiyun #define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun struct dsp_dtmf {
121*4882a593Smuzhiyun 	int		enable; /* dtmf is enabled */
122*4882a593Smuzhiyun 	int		treshold; /* above this is dtmf (square of) */
123*4882a593Smuzhiyun 	int		software; /* dtmf uses software decoding */
124*4882a593Smuzhiyun 	int		hardware; /* dtmf uses hardware decoding */
125*4882a593Smuzhiyun 	int		size; /* number of bytes in buffer */
126*4882a593Smuzhiyun 	signed short	buffer[DSP_DTMF_NPOINTS];
127*4882a593Smuzhiyun 	/* buffers one full dtmf frame */
128*4882a593Smuzhiyun 	u8		lastwhat, lastdigit;
129*4882a593Smuzhiyun 	int		count;
130*4882a593Smuzhiyun 	u8		digits[16]; /* dtmf result */
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun /******************
135*4882a593Smuzhiyun  * pipeline stuff *
136*4882a593Smuzhiyun  ******************/
137*4882a593Smuzhiyun struct dsp_pipeline {
138*4882a593Smuzhiyun 	rwlock_t  lock;
139*4882a593Smuzhiyun 	struct list_head list;
140*4882a593Smuzhiyun 	int inuse;
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun /***************
144*4882a593Smuzhiyun  * tones stuff *
145*4882a593Smuzhiyun  ***************/
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun struct dsp_tone {
148*4882a593Smuzhiyun 	int		software; /* tones are generated by software */
149*4882a593Smuzhiyun 	int		hardware; /* tones are generated by hardware */
150*4882a593Smuzhiyun 	int		tone;
151*4882a593Smuzhiyun 	void		*pattern;
152*4882a593Smuzhiyun 	int		count;
153*4882a593Smuzhiyun 	int		index;
154*4882a593Smuzhiyun 	struct timer_list tl;
155*4882a593Smuzhiyun };
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /***************
158*4882a593Smuzhiyun  * echo stuff *
159*4882a593Smuzhiyun  ***************/
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun struct dsp_echo {
162*4882a593Smuzhiyun 	int		software; /* echo is generated by software */
163*4882a593Smuzhiyun 	int		hardware; /* echo is generated by hardware */
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /*****************
167*4882a593Smuzhiyun  * general stuff *
168*4882a593Smuzhiyun  *****************/
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun struct dsp {
171*4882a593Smuzhiyun 	struct list_head list;
172*4882a593Smuzhiyun 	struct mISDNchannel	ch;
173*4882a593Smuzhiyun 	struct mISDNchannel	*up;
174*4882a593Smuzhiyun 	unsigned char	name[64];
175*4882a593Smuzhiyun 	int		b_active;
176*4882a593Smuzhiyun 	struct dsp_echo	echo;
177*4882a593Smuzhiyun 	int		rx_disabled; /* what the user wants */
178*4882a593Smuzhiyun 	int		rx_is_off; /* what the card is */
179*4882a593Smuzhiyun 	int		tx_mix;
180*4882a593Smuzhiyun 	struct dsp_tone	tone;
181*4882a593Smuzhiyun 	struct dsp_dtmf	dtmf;
182*4882a593Smuzhiyun 	int		tx_volume, rx_volume;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	/* queue for sending frames */
185*4882a593Smuzhiyun 	struct work_struct	workq;
186*4882a593Smuzhiyun 	struct sk_buff_head	sendq;
187*4882a593Smuzhiyun 	int		hdlc;	/* if mode is hdlc */
188*4882a593Smuzhiyun 	int		data_pending;	/* currently an unconfirmed frame */
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	/* conference stuff */
191*4882a593Smuzhiyun 	u32		conf_id;
192*4882a593Smuzhiyun 	struct dsp_conf	*conf;
193*4882a593Smuzhiyun 	struct dsp_conf_member
194*4882a593Smuzhiyun 	*member;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	/* buffer stuff */
197*4882a593Smuzhiyun 	int		rx_W; /* current write pos for data without timestamp */
198*4882a593Smuzhiyun 	int		rx_R; /* current read pos for transmit clock */
199*4882a593Smuzhiyun 	int		rx_init; /* if set, pointers will be adjusted first */
200*4882a593Smuzhiyun 	int		tx_W; /* current write pos for transmit data */
201*4882a593Smuzhiyun 	int		tx_R; /* current read pos for transmit clock */
202*4882a593Smuzhiyun 	int		rx_delay[MAX_SECONDS_JITTER_CHECK];
203*4882a593Smuzhiyun 	int		tx_delay[MAX_SECONDS_JITTER_CHECK];
204*4882a593Smuzhiyun 	u8		tx_buff[CMX_BUFF_SIZE];
205*4882a593Smuzhiyun 	u8		rx_buff[CMX_BUFF_SIZE];
206*4882a593Smuzhiyun 	int		last_tx; /* if set, we transmitted last poll interval */
207*4882a593Smuzhiyun 	int		cmx_delay; /* initial delay of buffers,
208*4882a593Smuzhiyun 				      or 0 for dynamic jitter buffer */
209*4882a593Smuzhiyun 	int		tx_dejitter; /* if set, dejitter tx buffer */
210*4882a593Smuzhiyun 	int		tx_data; /* enables tx-data of CMX to upper layer */
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	/* hardware stuff */
213*4882a593Smuzhiyun 	struct dsp_features features;
214*4882a593Smuzhiyun 	int		features_rx_off; /* set if rx_off is featured */
215*4882a593Smuzhiyun 	int		features_fill_empty; /* set if fill_empty is featured */
216*4882a593Smuzhiyun 	int		pcm_slot_rx; /* current PCM slot (or -1) */
217*4882a593Smuzhiyun 	int		pcm_bank_rx;
218*4882a593Smuzhiyun 	int		pcm_slot_tx;
219*4882a593Smuzhiyun 	int		pcm_bank_tx;
220*4882a593Smuzhiyun 	int		hfc_conf; /* unique id of current conference (or -1) */
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	/* encryption stuff */
223*4882a593Smuzhiyun 	int		bf_enable;
224*4882a593Smuzhiyun 	u32		bf_p[18];
225*4882a593Smuzhiyun 	u32		bf_s[1024];
226*4882a593Smuzhiyun 	int		bf_crypt_pos;
227*4882a593Smuzhiyun 	u8		bf_data_in[9];
228*4882a593Smuzhiyun 	u8		bf_crypt_out[9];
229*4882a593Smuzhiyun 	int		bf_decrypt_in_pos;
230*4882a593Smuzhiyun 	int		bf_decrypt_out_pos;
231*4882a593Smuzhiyun 	u8		bf_crypt_inring[16];
232*4882a593Smuzhiyun 	u8		bf_data_out[9];
233*4882a593Smuzhiyun 	int		bf_sync;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	struct dsp_pipeline
236*4882a593Smuzhiyun 	pipeline;
237*4882a593Smuzhiyun };
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /* functions */
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun extern void dsp_change_volume(struct sk_buff *skb, int volume);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun extern struct list_head dsp_ilist;
244*4882a593Smuzhiyun extern struct list_head conf_ilist;
245*4882a593Smuzhiyun extern void dsp_cmx_debug(struct dsp *dsp);
246*4882a593Smuzhiyun extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
247*4882a593Smuzhiyun extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
248*4882a593Smuzhiyun extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
249*4882a593Smuzhiyun extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
250*4882a593Smuzhiyun extern void dsp_cmx_send(void *arg);
251*4882a593Smuzhiyun extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
252*4882a593Smuzhiyun extern int dsp_cmx_del_conf_member(struct dsp *dsp);
253*4882a593Smuzhiyun extern int dsp_cmx_del_conf(struct dsp_conf *conf);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
256*4882a593Smuzhiyun extern void dsp_dtmf_hardware(struct dsp *dsp);
257*4882a593Smuzhiyun extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
258*4882a593Smuzhiyun 				    int fmt);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun extern int dsp_tone(struct dsp *dsp, int tone);
261*4882a593Smuzhiyun extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
262*4882a593Smuzhiyun extern void dsp_tone_timeout(struct timer_list *t);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len);
265*4882a593Smuzhiyun extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len);
266*4882a593Smuzhiyun extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen);
267*4882a593Smuzhiyun extern void dsp_bf_cleanup(struct dsp *dsp);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun extern int  dsp_pipeline_module_init(void);
270*4882a593Smuzhiyun extern void dsp_pipeline_module_exit(void);
271*4882a593Smuzhiyun extern int  dsp_pipeline_init(struct dsp_pipeline *pipeline);
272*4882a593Smuzhiyun extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
273*4882a593Smuzhiyun extern int  dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
274*4882a593Smuzhiyun extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
275*4882a593Smuzhiyun 				    int len);
276*4882a593Smuzhiyun extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
277*4882a593Smuzhiyun 				    int len, unsigned int txlen);
278