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