xref: /linux/drivers/isdn/mISDN/dsp_tones.c (revision bcf91745091ba3b0813fa79afb5d10b090ea745d)
1960366cfSKarsten Keil /*
2960366cfSKarsten Keil  * Audio support data for ISDN4Linux.
3960366cfSKarsten Keil  *
4960366cfSKarsten Keil  * Copyright Andreas Eversberg (jolly@eversberg.eu)
5960366cfSKarsten Keil  *
6960366cfSKarsten Keil  * This software may be used and distributed according to the terms
7960366cfSKarsten Keil  * of the GNU General Public License, incorporated herein by reference.
8960366cfSKarsten Keil  *
9960366cfSKarsten Keil  */
10960366cfSKarsten Keil 
11960366cfSKarsten Keil #include <linux/mISDNif.h>
12960366cfSKarsten Keil #include <linux/mISDNdsp.h>
13960366cfSKarsten Keil #include "core.h"
14960366cfSKarsten Keil #include "dsp.h"
15960366cfSKarsten Keil 
16960366cfSKarsten Keil 
17960366cfSKarsten Keil #define DATA_S sample_silence
18960366cfSKarsten Keil #define SIZE_S (&sizeof_silence)
19960366cfSKarsten Keil #define DATA_GA sample_german_all
20960366cfSKarsten Keil #define SIZE_GA (&sizeof_german_all)
21960366cfSKarsten Keil #define DATA_GO sample_german_old
22960366cfSKarsten Keil #define SIZE_GO (&sizeof_german_old)
23960366cfSKarsten Keil #define DATA_DT sample_american_dialtone
24960366cfSKarsten Keil #define SIZE_DT (&sizeof_american_dialtone)
25960366cfSKarsten Keil #define DATA_RI sample_american_ringing
26960366cfSKarsten Keil #define SIZE_RI (&sizeof_american_ringing)
27960366cfSKarsten Keil #define DATA_BU sample_american_busy
28960366cfSKarsten Keil #define SIZE_BU (&sizeof_american_busy)
29960366cfSKarsten Keil #define DATA_S1 sample_special1
30960366cfSKarsten Keil #define SIZE_S1 (&sizeof_special1)
31960366cfSKarsten Keil #define DATA_S2 sample_special2
32960366cfSKarsten Keil #define SIZE_S2 (&sizeof_special2)
33960366cfSKarsten Keil #define DATA_S3 sample_special3
34960366cfSKarsten Keil #define SIZE_S3 (&sizeof_special3)
35960366cfSKarsten Keil 
36960366cfSKarsten Keil /***************/
37960366cfSKarsten Keil /* tones loops */
38960366cfSKarsten Keil /***************/
39960366cfSKarsten Keil 
40960366cfSKarsten Keil /* all tones are alaw encoded */
41960366cfSKarsten Keil /* the last sample+1 is in phase with the first sample. the error is low */
42960366cfSKarsten Keil 
43960366cfSKarsten Keil static u8 sample_german_all[] = {
44960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
45960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
46960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
47960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
48960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
49960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
50960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
51960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
52960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
53960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
54960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
55960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
56960366cfSKarsten Keil };
57960366cfSKarsten Keil static u32 sizeof_german_all = sizeof(sample_german_all);
58960366cfSKarsten Keil 
59960366cfSKarsten Keil static u8 sample_german_old[] = {
60960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
61960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
62960366cfSKarsten Keil 	0x8c,
63960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
64960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
65960366cfSKarsten Keil 	0x8c,
66960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
67960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
68960366cfSKarsten Keil 	0x8c,
69960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
70960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
71960366cfSKarsten Keil 	0x8c,
72960366cfSKarsten Keil };
73960366cfSKarsten Keil static u32 sizeof_german_old = sizeof(sample_german_old);
74960366cfSKarsten Keil 
75960366cfSKarsten Keil static u8 sample_american_dialtone[] = {
76960366cfSKarsten Keil 	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
77960366cfSKarsten Keil 	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
78960366cfSKarsten Keil 	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
79960366cfSKarsten Keil 	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
80960366cfSKarsten Keil 	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
81960366cfSKarsten Keil 	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
82960366cfSKarsten Keil 	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
83960366cfSKarsten Keil 	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
84960366cfSKarsten Keil 	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
85960366cfSKarsten Keil 	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
86960366cfSKarsten Keil 	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
87960366cfSKarsten Keil 	0x6d, 0x91, 0x19,
88960366cfSKarsten Keil };
89960366cfSKarsten Keil static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
90960366cfSKarsten Keil 
91960366cfSKarsten Keil static u8 sample_american_ringing[] = {
92960366cfSKarsten Keil 	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
93960366cfSKarsten Keil 	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
94960366cfSKarsten Keil 	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
95960366cfSKarsten Keil 	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
96960366cfSKarsten Keil 	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
97960366cfSKarsten Keil 	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
98960366cfSKarsten Keil 	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
99960366cfSKarsten Keil 	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
100960366cfSKarsten Keil 	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
101960366cfSKarsten Keil 	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
102960366cfSKarsten Keil 	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
103960366cfSKarsten Keil 	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
104960366cfSKarsten Keil 	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
105960366cfSKarsten Keil 	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
106960366cfSKarsten Keil 	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
107960366cfSKarsten Keil 	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
108960366cfSKarsten Keil 	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
109960366cfSKarsten Keil 	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
110960366cfSKarsten Keil 	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
111960366cfSKarsten Keil 	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
112960366cfSKarsten Keil 	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
113960366cfSKarsten Keil };
114960366cfSKarsten Keil static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
115960366cfSKarsten Keil 
116960366cfSKarsten Keil static u8 sample_american_busy[] = {
117960366cfSKarsten Keil 	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
118960366cfSKarsten Keil 	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
119960366cfSKarsten Keil 	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
120960366cfSKarsten Keil 	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
121960366cfSKarsten Keil 	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
122960366cfSKarsten Keil 	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
123960366cfSKarsten Keil 	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
124960366cfSKarsten Keil 	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
125960366cfSKarsten Keil 	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
126960366cfSKarsten Keil 	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
127960366cfSKarsten Keil 	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
128960366cfSKarsten Keil 	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
129960366cfSKarsten Keil 	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
130960366cfSKarsten Keil 	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
131960366cfSKarsten Keil 	0x4d, 0x4d, 0x6d, 0x01,
132960366cfSKarsten Keil };
133960366cfSKarsten Keil static u32 sizeof_american_busy = sizeof(sample_american_busy);
134960366cfSKarsten Keil 
135960366cfSKarsten Keil static u8 sample_special1[] = {
136960366cfSKarsten Keil 	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
137960366cfSKarsten Keil 	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
138960366cfSKarsten Keil 	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
139960366cfSKarsten Keil 	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
140960366cfSKarsten Keil 	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
141960366cfSKarsten Keil 	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
142960366cfSKarsten Keil 	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
143960366cfSKarsten Keil 	0x6d, 0xbd, 0x2d,
144960366cfSKarsten Keil };
145960366cfSKarsten Keil static u32 sizeof_special1 = sizeof(sample_special1);
146960366cfSKarsten Keil 
147960366cfSKarsten Keil static u8 sample_special2[] = {
148960366cfSKarsten Keil 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
149960366cfSKarsten Keil 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
150960366cfSKarsten Keil 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
151960366cfSKarsten Keil 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
152960366cfSKarsten Keil 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
153960366cfSKarsten Keil 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
154960366cfSKarsten Keil 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
155960366cfSKarsten Keil 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
156960366cfSKarsten Keil 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
157960366cfSKarsten Keil 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
158960366cfSKarsten Keil };
159960366cfSKarsten Keil static u32 sizeof_special2 = sizeof(sample_special2);
160960366cfSKarsten Keil 
161960366cfSKarsten Keil static u8 sample_special3[] = {
162960366cfSKarsten Keil 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
163960366cfSKarsten Keil 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
164960366cfSKarsten Keil 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
165960366cfSKarsten Keil 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
166960366cfSKarsten Keil 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
167960366cfSKarsten Keil 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
168960366cfSKarsten Keil 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
169960366cfSKarsten Keil 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
170960366cfSKarsten Keil 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
171960366cfSKarsten Keil 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
172960366cfSKarsten Keil };
173960366cfSKarsten Keil static u32 sizeof_special3 = sizeof(sample_special3);
174960366cfSKarsten Keil 
175960366cfSKarsten Keil static u8 sample_silence[] = {
176960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
177960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
178960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
179960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
180960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
181960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
182960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
183960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
184960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
185960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
186960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
187960366cfSKarsten Keil 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
188960366cfSKarsten Keil };
189960366cfSKarsten Keil static u32 sizeof_silence = sizeof(sample_silence);
190960366cfSKarsten Keil 
191960366cfSKarsten Keil struct tones_samples {
192960366cfSKarsten Keil 	u32 *len;
193960366cfSKarsten Keil 	u8 *data;
194960366cfSKarsten Keil };
195960366cfSKarsten Keil static struct
196960366cfSKarsten Keil tones_samples samples[] = {
197960366cfSKarsten Keil 	{&sizeof_german_all, sample_german_all},
198960366cfSKarsten Keil 	{&sizeof_german_old, sample_german_old},
199960366cfSKarsten Keil 	{&sizeof_american_dialtone, sample_american_dialtone},
200960366cfSKarsten Keil 	{&sizeof_american_ringing, sample_american_ringing},
201960366cfSKarsten Keil 	{&sizeof_american_busy, sample_american_busy},
202960366cfSKarsten Keil 	{&sizeof_special1, sample_special1},
203960366cfSKarsten Keil 	{&sizeof_special2, sample_special2},
204960366cfSKarsten Keil 	{&sizeof_special3, sample_special3},
205960366cfSKarsten Keil 	{NULL, NULL},
206960366cfSKarsten Keil };
207960366cfSKarsten Keil 
208960366cfSKarsten Keil /***********************************
209960366cfSKarsten Keil  * generate ulaw from alaw samples *
210960366cfSKarsten Keil  ***********************************/
211960366cfSKarsten Keil 
212960366cfSKarsten Keil void
213960366cfSKarsten Keil dsp_audio_generate_ulaw_samples(void)
214960366cfSKarsten Keil {
215960366cfSKarsten Keil 	int i, j;
216960366cfSKarsten Keil 
217960366cfSKarsten Keil 	i = 0;
218960366cfSKarsten Keil 	while (samples[i].len) {
219960366cfSKarsten Keil 		j = 0;
220960366cfSKarsten Keil 		while (j < (*samples[i].len)) {
221960366cfSKarsten Keil 			samples[i].data[j] =
222960366cfSKarsten Keil 				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
223960366cfSKarsten Keil 			j++;
224960366cfSKarsten Keil 		}
225960366cfSKarsten Keil 		i++;
226960366cfSKarsten Keil 	}
227960366cfSKarsten Keil }
228960366cfSKarsten Keil 
229960366cfSKarsten Keil 
230960366cfSKarsten Keil /****************************
231960366cfSKarsten Keil  * tone sequence definition *
232960366cfSKarsten Keil  ****************************/
233960366cfSKarsten Keil 
234960366cfSKarsten Keil struct pattern {
235960366cfSKarsten Keil 	int tone;
236960366cfSKarsten Keil 	u8 *data[10];
237960366cfSKarsten Keil 	u32 *siz[10];
238960366cfSKarsten Keil 	u32 seq[10];
239960366cfSKarsten Keil } pattern[] = {
240960366cfSKarsten Keil 	{TONE_GERMAN_DIALTONE,
241*bcf91745SHannes Eder 	{DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
242*bcf91745SHannes Eder 	{SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243960366cfSKarsten Keil 	{1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
244960366cfSKarsten Keil 
245960366cfSKarsten Keil 	{TONE_GERMAN_OLDDIALTONE,
246*bcf91745SHannes Eder 	{DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
247*bcf91745SHannes Eder 	{SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248960366cfSKarsten Keil 	{1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
249960366cfSKarsten Keil 
250960366cfSKarsten Keil 	{TONE_AMERICAN_DIALTONE,
251*bcf91745SHannes Eder 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
252*bcf91745SHannes Eder 	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253960366cfSKarsten Keil 	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
254960366cfSKarsten Keil 
255960366cfSKarsten Keil 	{TONE_GERMAN_DIALPBX,
256*bcf91745SHannes Eder 	{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL},
257*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL},
258960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
259960366cfSKarsten Keil 
260960366cfSKarsten Keil 	{TONE_GERMAN_OLDDIALPBX,
261*bcf91745SHannes Eder 	{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL},
262*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL},
263960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
264960366cfSKarsten Keil 
265960366cfSKarsten Keil 	{TONE_AMERICAN_DIALPBX,
266*bcf91745SHannes Eder 	{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL},
267*bcf91745SHannes Eder 	{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL},
268960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269960366cfSKarsten Keil 
270960366cfSKarsten Keil 	{TONE_GERMAN_RINGING,
271*bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
272*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
273960366cfSKarsten Keil 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
274960366cfSKarsten Keil 
275960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGING,
276*bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
277*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
278960366cfSKarsten Keil 	{8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
279960366cfSKarsten Keil 
280960366cfSKarsten Keil 	{TONE_AMERICAN_RINGING,
281*bcf91745SHannes Eder 	{DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
282*bcf91745SHannes Eder 	{SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
283960366cfSKarsten Keil 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
284960366cfSKarsten Keil 
285960366cfSKarsten Keil 	{TONE_GERMAN_RINGPBX,
286*bcf91745SHannes Eder 	{DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
287*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
288960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
289960366cfSKarsten Keil 
290960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGPBX,
291*bcf91745SHannes Eder 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
292*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
293960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
294960366cfSKarsten Keil 
295960366cfSKarsten Keil 	{TONE_AMERICAN_RINGPBX,
296*bcf91745SHannes Eder 	{DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
297*bcf91745SHannes Eder 	{SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
298960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
299960366cfSKarsten Keil 
300960366cfSKarsten Keil 	{TONE_GERMAN_BUSY,
301*bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
302*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
303960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
304960366cfSKarsten Keil 
305960366cfSKarsten Keil 	{TONE_GERMAN_OLDBUSY,
306*bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
307*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
308960366cfSKarsten Keil 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
309960366cfSKarsten Keil 
310960366cfSKarsten Keil 	{TONE_AMERICAN_BUSY,
311*bcf91745SHannes Eder 	{DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
312*bcf91745SHannes Eder 	{SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
313960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
314960366cfSKarsten Keil 
315960366cfSKarsten Keil 	{TONE_GERMAN_HANGUP,
316*bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
317*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
318960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
319960366cfSKarsten Keil 
320960366cfSKarsten Keil 	{TONE_GERMAN_OLDHANGUP,
321*bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
322*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
323960366cfSKarsten Keil 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
324960366cfSKarsten Keil 
325960366cfSKarsten Keil 	{TONE_AMERICAN_HANGUP,
326*bcf91745SHannes Eder 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
327*bcf91745SHannes Eder 	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
328960366cfSKarsten Keil 	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
329960366cfSKarsten Keil 
330960366cfSKarsten Keil 	{TONE_SPECIAL_INFO,
331*bcf91745SHannes Eder 	{DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
332*bcf91745SHannes Eder 	{SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
333960366cfSKarsten Keil 	{2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
334960366cfSKarsten Keil 
335960366cfSKarsten Keil 	{TONE_GERMAN_GASSENBESETZT,
336*bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
337*bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
338960366cfSKarsten Keil 	{2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
339960366cfSKarsten Keil 
340960366cfSKarsten Keil 	{TONE_GERMAN_AUFSCHALTTON,
341*bcf91745SHannes Eder 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
342*bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
343960366cfSKarsten Keil 	{1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
344960366cfSKarsten Keil 
345960366cfSKarsten Keil 	{0,
346*bcf91745SHannes Eder 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
347*bcf91745SHannes Eder 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
348960366cfSKarsten Keil 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
349960366cfSKarsten Keil };
350960366cfSKarsten Keil 
351960366cfSKarsten Keil /******************
352960366cfSKarsten Keil  * copy tone data *
353960366cfSKarsten Keil  ******************/
354960366cfSKarsten Keil 
355960366cfSKarsten Keil /* an sk_buff is generated from the number of samples needed.
356960366cfSKarsten Keil  * the count will be changed and may begin from 0 each pattern period.
357960366cfSKarsten Keil  * the clue is to precalculate the pointers and legths to use only one
358960366cfSKarsten Keil  * memcpy per function call, or two memcpy if the tone sequence changes.
359960366cfSKarsten Keil  *
360960366cfSKarsten Keil  * pattern - the type of the pattern
361960366cfSKarsten Keil  * count - the sample from the beginning of the pattern (phase)
362960366cfSKarsten Keil  * len - the number of bytes
363960366cfSKarsten Keil  *
364960366cfSKarsten Keil  * return - the sk_buff with the sample
365960366cfSKarsten Keil  *
366960366cfSKarsten Keil  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
367960366cfSKarsten Keil  */
368960366cfSKarsten Keil void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
369960366cfSKarsten Keil {
370960366cfSKarsten Keil 	int index, count, start, num;
371960366cfSKarsten Keil 	struct pattern *pat;
372960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
373960366cfSKarsten Keil 
374960366cfSKarsten Keil 	/* if we have no tone, we copy silence */
375960366cfSKarsten Keil 	if (!tone->tone) {
376960366cfSKarsten Keil 		memset(data, dsp_silence, len);
377960366cfSKarsten Keil 		return;
378960366cfSKarsten Keil 	}
379960366cfSKarsten Keil 
380960366cfSKarsten Keil 	/* process pattern */
381960366cfSKarsten Keil 	pat = (struct pattern *)tone->pattern;
382960366cfSKarsten Keil 		/* points to the current pattern */
383960366cfSKarsten Keil 	index = tone->index; /* gives current sequence index */
384960366cfSKarsten Keil 	count = tone->count; /* gives current sample */
385960366cfSKarsten Keil 
386960366cfSKarsten Keil 	/* copy sample */
387960366cfSKarsten Keil 	while (len) {
388960366cfSKarsten Keil 		/* find sample to start with */
389960366cfSKarsten Keil 		while (42) {
390960366cfSKarsten Keil 			/* warp arround */
391960366cfSKarsten Keil 			if (!pat->seq[index]) {
392960366cfSKarsten Keil 				count = 0;
393960366cfSKarsten Keil 				index = 0;
394960366cfSKarsten Keil 			}
395960366cfSKarsten Keil 			/* check if we are currently playing this tone */
396960366cfSKarsten Keil 			if (count < pat->seq[index])
397960366cfSKarsten Keil 				break;
398960366cfSKarsten Keil 			if (dsp_debug & DEBUG_DSP_TONE)
399960366cfSKarsten Keil 				printk(KERN_DEBUG "%s: reaching next sequence "
400960366cfSKarsten Keil 					"(index=%d)\n", __func__, index);
401960366cfSKarsten Keil 			count -= pat->seq[index];
402960366cfSKarsten Keil 			index++;
403960366cfSKarsten Keil 		}
404960366cfSKarsten Keil 		/* calculate start and number of samples */
405960366cfSKarsten Keil 		start = count % (*(pat->siz[index]));
406960366cfSKarsten Keil 		num = len;
407960366cfSKarsten Keil 		if (num+count > pat->seq[index])
408960366cfSKarsten Keil 			num = pat->seq[index] - count;
409960366cfSKarsten Keil 		if (num+start > (*(pat->siz[index])))
410960366cfSKarsten Keil 			num = (*(pat->siz[index])) - start;
411960366cfSKarsten Keil 		/* copy memory */
412960366cfSKarsten Keil 		memcpy(data, pat->data[index]+start, num);
413960366cfSKarsten Keil 		/* reduce length */
414960366cfSKarsten Keil 		data += num;
415960366cfSKarsten Keil 		count += num;
416960366cfSKarsten Keil 		len -= num;
417960366cfSKarsten Keil 	}
418960366cfSKarsten Keil 	tone->index = index;
419960366cfSKarsten Keil 	tone->count = count;
420960366cfSKarsten Keil 
421960366cfSKarsten Keil 	/* return sk_buff */
422960366cfSKarsten Keil 	return;
423960366cfSKarsten Keil }
424960366cfSKarsten Keil 
425960366cfSKarsten Keil 
426960366cfSKarsten Keil /*******************************
427960366cfSKarsten Keil  * send HW message to hfc card *
428960366cfSKarsten Keil  *******************************/
429960366cfSKarsten Keil 
430960366cfSKarsten Keil static void
431960366cfSKarsten Keil dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
432960366cfSKarsten Keil {
433960366cfSKarsten Keil 	struct sk_buff *nskb;
434960366cfSKarsten Keil 
435960366cfSKarsten Keil 	/* unlocking is not required, because we don't expect a response */
436960366cfSKarsten Keil 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
437960366cfSKarsten Keil 		(len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample,
438960366cfSKarsten Keil 		GFP_ATOMIC);
439960366cfSKarsten Keil 	if (nskb) {
440960366cfSKarsten Keil 		if (dsp->ch.peer) {
441960366cfSKarsten Keil 			if (dsp->ch.recv(dsp->ch.peer, nskb))
442960366cfSKarsten Keil 				dev_kfree_skb(nskb);
443960366cfSKarsten Keil 		} else
444960366cfSKarsten Keil 			dev_kfree_skb(nskb);
445960366cfSKarsten Keil 	}
446960366cfSKarsten Keil }
447960366cfSKarsten Keil 
448960366cfSKarsten Keil 
449960366cfSKarsten Keil /*****************
450960366cfSKarsten Keil  * timer expires *
451960366cfSKarsten Keil  *****************/
452960366cfSKarsten Keil void
453960366cfSKarsten Keil dsp_tone_timeout(void *arg)
454960366cfSKarsten Keil {
455960366cfSKarsten Keil 	struct dsp *dsp = arg;
456960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
457960366cfSKarsten Keil 	struct pattern *pat = (struct pattern *)tone->pattern;
458960366cfSKarsten Keil 	int index = tone->index;
459960366cfSKarsten Keil 
460960366cfSKarsten Keil 	if (!tone->tone)
461960366cfSKarsten Keil 		return;
462960366cfSKarsten Keil 
463960366cfSKarsten Keil 	index++;
464960366cfSKarsten Keil 	if (!pat->seq[index])
465960366cfSKarsten Keil 		index = 0;
466960366cfSKarsten Keil 	tone->index = index;
467960366cfSKarsten Keil 
468960366cfSKarsten Keil 	/* set next tone */
469960366cfSKarsten Keil 	if (pat->data[index] == DATA_S)
470*bcf91745SHannes Eder 		dsp_tone_hw_message(dsp, NULL, 0);
471960366cfSKarsten Keil 	else
472960366cfSKarsten Keil 		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
473960366cfSKarsten Keil 	/* set timer */
474960366cfSKarsten Keil 	init_timer(&tone->tl);
475960366cfSKarsten Keil 	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
476960366cfSKarsten Keil 	add_timer(&tone->tl);
477960366cfSKarsten Keil }
478960366cfSKarsten Keil 
479960366cfSKarsten Keil 
480960366cfSKarsten Keil /********************
481960366cfSKarsten Keil  * set/release tone *
482960366cfSKarsten Keil  ********************/
483960366cfSKarsten Keil 
484960366cfSKarsten Keil /*
485960366cfSKarsten Keil  * tones are relaized by streaming or by special loop commands if supported
486960366cfSKarsten Keil  * by hardware. when hardware is used, the patterns will be controlled by
487960366cfSKarsten Keil  * timers.
488960366cfSKarsten Keil  */
489960366cfSKarsten Keil int
490960366cfSKarsten Keil dsp_tone(struct dsp *dsp, int tone)
491960366cfSKarsten Keil {
492960366cfSKarsten Keil 	struct pattern *pat;
493960366cfSKarsten Keil 	int i;
494960366cfSKarsten Keil 	struct dsp_tone *tonet = &dsp->tone;
495960366cfSKarsten Keil 
496960366cfSKarsten Keil 	tonet->software = 0;
497960366cfSKarsten Keil 	tonet->hardware = 0;
498960366cfSKarsten Keil 
499960366cfSKarsten Keil 	/* we turn off the tone */
500960366cfSKarsten Keil 	if (!tone) {
501960366cfSKarsten Keil 		if (dsp->features.hfc_loops)
502960366cfSKarsten Keil 		if (timer_pending(&tonet->tl))
503960366cfSKarsten Keil 			del_timer(&tonet->tl);
504960366cfSKarsten Keil 		if (dsp->features.hfc_loops)
505960366cfSKarsten Keil 			dsp_tone_hw_message(dsp, NULL, 0);
506960366cfSKarsten Keil 		tonet->tone = 0;
507960366cfSKarsten Keil 		return 0;
508960366cfSKarsten Keil 	}
509960366cfSKarsten Keil 
510960366cfSKarsten Keil 	pat = NULL;
511960366cfSKarsten Keil 	i = 0;
512960366cfSKarsten Keil 	while (pattern[i].tone) {
513960366cfSKarsten Keil 		if (pattern[i].tone == tone) {
514960366cfSKarsten Keil 			pat = &pattern[i];
515960366cfSKarsten Keil 			break;
516960366cfSKarsten Keil 		}
517960366cfSKarsten Keil 		i++;
518960366cfSKarsten Keil 	}
519960366cfSKarsten Keil 	if (!pat) {
520960366cfSKarsten Keil 		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
521960366cfSKarsten Keil 		return -EINVAL;
522960366cfSKarsten Keil 	}
523960366cfSKarsten Keil 	if (dsp_debug & DEBUG_DSP_TONE)
524960366cfSKarsten Keil 		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
525960366cfSKarsten Keil 			__func__, tone, 0);
526960366cfSKarsten Keil 	tonet->tone = tone;
527960366cfSKarsten Keil 	tonet->pattern = pat;
528960366cfSKarsten Keil 	tonet->index = 0;
529960366cfSKarsten Keil 	tonet->count = 0;
530960366cfSKarsten Keil 
531960366cfSKarsten Keil 	if (dsp->features.hfc_loops) {
532960366cfSKarsten Keil 		tonet->hardware = 1;
533960366cfSKarsten Keil 		/* set first tone */
534960366cfSKarsten Keil 		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
535960366cfSKarsten Keil 		/* set timer */
536960366cfSKarsten Keil 		if (timer_pending(&tonet->tl))
537960366cfSKarsten Keil 			del_timer(&tonet->tl);
538960366cfSKarsten Keil 		init_timer(&tonet->tl);
539960366cfSKarsten Keil 		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
540960366cfSKarsten Keil 		add_timer(&tonet->tl);
541960366cfSKarsten Keil 	} else {
542960366cfSKarsten Keil 		tonet->software = 1;
543960366cfSKarsten Keil 	}
544960366cfSKarsten Keil 
545960366cfSKarsten Keil 	return 0;
546960366cfSKarsten Keil }
547960366cfSKarsten Keil 
548960366cfSKarsten Keil 
549960366cfSKarsten Keil 
550960366cfSKarsten Keil 
551960366cfSKarsten Keil 
552