Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dsp_tones.c
Go to the documentation of this file.
1 /*
2  * Audio support data for ISDN4Linux.
3  *
4  * Copyright Andreas Eversberg ([email protected])
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 
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
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[] = {
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 
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 
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 
258  NULL},
260  NULL},
261  {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262 
265  NULL},
267  NULL},
268  {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269 
272  NULL},
274  NULL},
275  {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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;
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
461 {
462  struct dsp *dsp = arg;
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  init_timer(&tone->tl);
482  tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
483  add_timer(&tone->tl);
484 }
485 
486 
487 /********************
488  * set/release tone *
489  ********************/
490 
491 /*
492  * tones are relaized by streaming or by special loop commands if supported
493  * by hardware. when hardware is used, the patterns will be controlled by
494  * timers.
495  */
496 int
497 dsp_tone(struct dsp *dsp, int tone)
498 {
499  struct pattern *pat;
500  int i;
501  struct dsp_tone *tonet = &dsp->tone;
502 
503  tonet->software = 0;
504  tonet->hardware = 0;
505 
506  /* we turn off the tone */
507  if (!tone) {
508  if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
509  del_timer(&tonet->tl);
510  if (dsp->features.hfc_loops)
511  dsp_tone_hw_message(dsp, NULL, 0);
512  tonet->tone = 0;
513  return 0;
514  }
515 
516  pat = NULL;
517  i = 0;
518  while (pattern[i].tone) {
519  if (pattern[i].tone == tone) {
520  pat = &pattern[i];
521  break;
522  }
523  i++;
524  }
525  if (!pat) {
526  printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
527  return -EINVAL;
528  }
530  printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
531  __func__, tone, 0);
532  tonet->tone = tone;
533  tonet->pattern = pat;
534  tonet->index = 0;
535  tonet->count = 0;
536 
537  if (dsp->features.hfc_loops) {
538  tonet->hardware = 1;
539  /* set first tone */
540  dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
541  /* set timer */
542  if (timer_pending(&tonet->tl))
543  del_timer(&tonet->tl);
544  init_timer(&tonet->tl);
545  tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
546  add_timer(&tonet->tl);
547  } else {
548  tonet->software = 1;
549  }
550 
551  return 0;
552 }