xref: /linux/drivers/isdn/mISDN/dsp_tones.c (revision ba199dc909a20fe62270ae4e93f263987bb9d119)
1 /*
2  * Audio support data for ISDN4Linux.
3  *
4  * Copyright Andreas Eversberg (jolly@eversberg.eu)
5  *
6  * This software may be used and distributed according to the terms
7  * of the GNU General Public License, incorporated herein by reference.
8  *
9  */
10 
11 #include <linux/gfp.h>
12 #include <linux/mISDNif.h>
13 #include <linux/mISDNdsp.h>
14 #include "core.h"
15 #include "dsp.h"
16 
17 
18 #define DATA_S sample_silence
19 #define SIZE_S (&sizeof_silence)
20 #define DATA_GA sample_german_all
21 #define SIZE_GA (&sizeof_german_all)
22 #define DATA_GO sample_german_old
23 #define SIZE_GO (&sizeof_german_old)
24 #define DATA_DT sample_american_dialtone
25 #define SIZE_DT (&sizeof_american_dialtone)
26 #define DATA_RI sample_american_ringing
27 #define SIZE_RI (&sizeof_american_ringing)
28 #define DATA_BU sample_american_busy
29 #define SIZE_BU (&sizeof_american_busy)
30 #define DATA_S1 sample_special1
31 #define SIZE_S1 (&sizeof_special1)
32 #define DATA_S2 sample_special2
33 #define SIZE_S2 (&sizeof_special2)
34 #define DATA_S3 sample_special3
35 #define SIZE_S3 (&sizeof_special3)
36 
37 /***************/
38 /* tones loops */
39 /***************/
40 
41 /* all tones are alaw encoded */
42 /* the last sample+1 is in phase with the first sample. the error is low */
43 
44 static u8 sample_german_all[] = {
45 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
46 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
47 	0xdc, 0xfc, 0x6c,
48 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
49 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
50 	0xdc, 0xfc, 0x6c,
51 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
52 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
53 	0xdc, 0xfc, 0x6c,
54 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
55 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
56 	0xdc, 0xfc, 0x6c,
57 };
58 static u32 sizeof_german_all = sizeof(sample_german_all);
59 
60 static u8 sample_german_old[] = {
61 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
62 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
63 	0x8c,
64 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
65 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
66 	0x8c,
67 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
68 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
69 	0x8c,
70 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
71 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
72 	0x8c,
73 };
74 static u32 sizeof_german_old = sizeof(sample_german_old);
75 
76 static u8 sample_american_dialtone[] = {
77 	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
78 	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
79 	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
80 	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
81 	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
82 	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
83 	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
84 	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
85 	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
86 	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
87 	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
88 	0x6d, 0x91, 0x19,
89 };
90 static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
91 
92 static u8 sample_american_ringing[] = {
93 	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
94 	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
95 	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
96 	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
97 	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
98 	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
99 	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
100 	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
101 	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
102 	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
103 	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
104 	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
105 	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
106 	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
107 	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
108 	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
109 	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
110 	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
111 	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
112 	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
113 	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
114 };
115 static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
116 
117 static u8 sample_american_busy[] = {
118 	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
119 	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
120 	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
121 	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
122 	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
123 	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
124 	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
125 	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
126 	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
127 	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
128 	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
129 	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
130 	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
131 	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
132 	0x4d, 0x4d, 0x6d, 0x01,
133 };
134 static u32 sizeof_american_busy = sizeof(sample_american_busy);
135 
136 static u8 sample_special1[] = {
137 	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
138 	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
139 	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
140 	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
141 	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
142 	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
143 	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
144 	0x6d, 0xbd, 0x2d,
145 };
146 static u32 sizeof_special1 = sizeof(sample_special1);
147 
148 static u8 sample_special2[] = {
149 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
150 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
151 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
152 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
153 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
154 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
155 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
156 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
157 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
158 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
159 };
160 static u32 sizeof_special2 = sizeof(sample_special2);
161 
162 static u8 sample_special3[] = {
163 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
164 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
165 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
166 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
167 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
168 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
169 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
170 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
171 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
172 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
173 };
174 static u32 sizeof_special3 = sizeof(sample_special3);
175 
176 static u8 sample_silence[] = {
177 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
178 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
179 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
180 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
181 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
182 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
183 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
184 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
185 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
186 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
187 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
188 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
189 };
190 static u32 sizeof_silence = sizeof(sample_silence);
191 
192 struct tones_samples {
193 	u32 *len;
194 	u8 *data;
195 };
196 static struct
197 tones_samples samples[] = {
198 	{&sizeof_german_all, sample_german_all},
199 	{&sizeof_german_old, sample_german_old},
200 	{&sizeof_american_dialtone, sample_american_dialtone},
201 	{&sizeof_american_ringing, sample_american_ringing},
202 	{&sizeof_american_busy, sample_american_busy},
203 	{&sizeof_special1, sample_special1},
204 	{&sizeof_special2, sample_special2},
205 	{&sizeof_special3, sample_special3},
206 	{NULL, NULL},
207 };
208 
209 /***********************************
210  * generate ulaw from alaw samples *
211  ***********************************/
212 
213 void
214 dsp_audio_generate_ulaw_samples(void)
215 {
216 	int i, j;
217 
218 	i = 0;
219 	while (samples[i].len) {
220 		j = 0;
221 		while (j < (*samples[i].len)) {
222 			samples[i].data[j] =
223 				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
224 			j++;
225 		}
226 		i++;
227 	}
228 }
229 
230 
231 /****************************
232  * tone sequence definition *
233  ****************************/
234 
235 static struct pattern {
236 	int tone;
237 	u8 *data[10];
238 	u32 *siz[10];
239 	u32 seq[10];
240 } pattern[] = {
241 	{TONE_GERMAN_DIALTONE,
242 	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243 	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
244 	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
245 
246 	{TONE_GERMAN_OLDDIALTONE,
247 	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248 	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
249 	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
250 
251 	{TONE_AMERICAN_DIALTONE,
252 	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253 	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
254 	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
255 
256 	{TONE_GERMAN_DIALPBX,
257 	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
258 	  NULL},
259 	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
260 	  NULL},
261 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262 
263 	{TONE_GERMAN_OLDDIALPBX,
264 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
265 	  NULL},
266 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
267 	  NULL},
268 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269 
270 	{TONE_AMERICAN_DIALPBX,
271 	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
272 	  NULL},
273 	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
274 	  NULL},
275 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276 
277 	{TONE_GERMAN_RINGING,
278 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
279 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
280 	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
281 
282 	{TONE_GERMAN_OLDRINGING,
283 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
284 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
285 	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
286 
287 	{TONE_AMERICAN_RINGING,
288 	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
289 	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
290 	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
291 
292 	{TONE_GERMAN_RINGPBX,
293 	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
294 	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
295 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
296 
297 	{TONE_GERMAN_OLDRINGPBX,
298 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
299 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
300 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
301 
302 	{TONE_AMERICAN_RINGPBX,
303 	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
304 	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
305 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
306 
307 	{TONE_GERMAN_BUSY,
308 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
309 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
310 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
311 
312 	{TONE_GERMAN_OLDBUSY,
313 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
314 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
315 	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
316 
317 	{TONE_AMERICAN_BUSY,
318 	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
319 	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
320 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
321 
322 	{TONE_GERMAN_HANGUP,
323 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
324 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
325 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
326 
327 	{TONE_GERMAN_OLDHANGUP,
328 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
329 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
330 	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
331 
332 	{TONE_AMERICAN_HANGUP,
333 	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334 	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
335 	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
336 
337 	{TONE_SPECIAL_INFO,
338 	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
339 	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
340 	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
341 
342 	{TONE_GERMAN_GASSENBESETZT,
343 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
344 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
345 	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
346 
347 	{TONE_GERMAN_AUFSCHALTTON,
348 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
349 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
350 	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
351 
352 	{0,
353 	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354 	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
355 	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
356 };
357 
358 /******************
359  * copy tone data *
360  ******************/
361 
362 /* an sk_buff is generated from the number of samples needed.
363  * the count will be changed and may begin from 0 each pattern period.
364  * the clue is to precalculate the pointers and legths to use only one
365  * memcpy per function call, or two memcpy if the tone sequence changes.
366  *
367  * pattern - the type of the pattern
368  * count - the sample from the beginning of the pattern (phase)
369  * len - the number of bytes
370  *
371  * return - the sk_buff with the sample
372  *
373  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
374  */
375 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
376 {
377 	int index, count, start, num;
378 	struct pattern *pat;
379 	struct dsp_tone *tone = &dsp->tone;
380 
381 	/* if we have no tone, we copy silence */
382 	if (!tone->tone) {
383 		memset(data, dsp_silence, len);
384 		return;
385 	}
386 
387 	/* process pattern */
388 	pat = (struct pattern *)tone->pattern;
389 	/* points to the current pattern */
390 	index = tone->index; /* gives current sequence index */
391 	count = tone->count; /* gives current sample */
392 
393 	/* copy sample */
394 	while (len) {
395 		/* find sample to start with */
396 		while (42) {
397 			/* wrap around */
398 			if (!pat->seq[index]) {
399 				count = 0;
400 				index = 0;
401 			}
402 			/* check if we are currently playing this tone */
403 			if (count < pat->seq[index])
404 				break;
405 			if (dsp_debug & DEBUG_DSP_TONE)
406 				printk(KERN_DEBUG "%s: reaching next sequence "
407 				       "(index=%d)\n", __func__, index);
408 			count -= pat->seq[index];
409 			index++;
410 		}
411 		/* calculate start and number of samples */
412 		start = count % (*(pat->siz[index]));
413 		num = len;
414 		if (num + count > pat->seq[index])
415 			num = pat->seq[index] - count;
416 		if (num + start > (*(pat->siz[index])))
417 			num = (*(pat->siz[index])) - start;
418 		/* copy memory */
419 		memcpy(data, pat->data[index] + start, num);
420 		/* reduce length */
421 		data += num;
422 		count += num;
423 		len -= num;
424 	}
425 	tone->index = index;
426 	tone->count = count;
427 
428 	/* return sk_buff */
429 	return;
430 }
431 
432 
433 /*******************************
434  * send HW message to hfc card *
435  *******************************/
436 
437 static void
438 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
439 {
440 	struct sk_buff *nskb;
441 
442 	/* unlocking is not required, because we don't expect a response */
443 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
444 				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
445 				GFP_ATOMIC);
446 	if (nskb) {
447 		if (dsp->ch.peer) {
448 			if (dsp->ch.recv(dsp->ch.peer, nskb))
449 				dev_kfree_skb(nskb);
450 		} else
451 			dev_kfree_skb(nskb);
452 	}
453 }
454 
455 
456 /*****************
457  * timer expires *
458  *****************/
459 void
460 dsp_tone_timeout(struct timer_list *t)
461 {
462 	struct dsp *dsp = from_timer(dsp, t, tone.tl);
463 	struct dsp_tone *tone = &dsp->tone;
464 	struct pattern *pat = (struct pattern *)tone->pattern;
465 	int index = tone->index;
466 
467 	if (!tone->tone)
468 		return;
469 
470 	index++;
471 	if (!pat->seq[index])
472 		index = 0;
473 	tone->index = index;
474 
475 	/* set next tone */
476 	if (pat->data[index] == DATA_S)
477 		dsp_tone_hw_message(dsp, NULL, 0);
478 	else
479 		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
480 	/* set timer */
481 	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
482 	add_timer(&tone->tl);
483 }
484 
485 
486 /********************
487  * set/release tone *
488  ********************/
489 
490 /*
491  * tones are relaized by streaming or by special loop commands if supported
492  * by hardware. when hardware is used, the patterns will be controlled by
493  * timers.
494  */
495 int
496 dsp_tone(struct dsp *dsp, int tone)
497 {
498 	struct pattern *pat;
499 	int i;
500 	struct dsp_tone *tonet = &dsp->tone;
501 
502 	tonet->software = 0;
503 	tonet->hardware = 0;
504 
505 	/* we turn off the tone */
506 	if (!tone) {
507 		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
508 			del_timer(&tonet->tl);
509 		if (dsp->features.hfc_loops)
510 			dsp_tone_hw_message(dsp, NULL, 0);
511 		tonet->tone = 0;
512 		return 0;
513 	}
514 
515 	pat = NULL;
516 	i = 0;
517 	while (pattern[i].tone) {
518 		if (pattern[i].tone == tone) {
519 			pat = &pattern[i];
520 			break;
521 		}
522 		i++;
523 	}
524 	if (!pat) {
525 		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
526 		return -EINVAL;
527 	}
528 	if (dsp_debug & DEBUG_DSP_TONE)
529 		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
530 		       __func__, tone, 0);
531 	tonet->tone = tone;
532 	tonet->pattern = pat;
533 	tonet->index = 0;
534 	tonet->count = 0;
535 
536 	if (dsp->features.hfc_loops) {
537 		tonet->hardware = 1;
538 		/* set first tone */
539 		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
540 		/* set timer */
541 		if (timer_pending(&tonet->tl))
542 			del_timer(&tonet->tl);
543 		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
544 		add_timer(&tonet->tl);
545 	} else {
546 		tonet->software = 1;
547 	}
548 
549 	return 0;
550 }
551