xref: /linux/drivers/isdn/mISDN/dsp_tones.c (revision eac74af9b547e29c9634ed5eff4d514349e73310)
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 
2345b834354SHannes Eder static 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,
241bcf91745SHannes Eder 	{DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
242bcf91745SHannes 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,
246bcf91745SHannes Eder 	{DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
247bcf91745SHannes 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,
251bcf91745SHannes Eder 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
252bcf91745SHannes 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*eac74af9SKarsten Keil 	{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
257*eac74af9SKarsten Keil 		NULL},
258*eac74af9SKarsten Keil 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
259*eac74af9SKarsten Keil 		NULL},
260960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
261960366cfSKarsten Keil 
262960366cfSKarsten Keil 	{TONE_GERMAN_OLDDIALPBX,
263*eac74af9SKarsten Keil 	{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
264*eac74af9SKarsten Keil 		NULL},
265*eac74af9SKarsten Keil 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
266*eac74af9SKarsten Keil 		NULL},
267960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
268960366cfSKarsten Keil 
269960366cfSKarsten Keil 	{TONE_AMERICAN_DIALPBX,
270*eac74af9SKarsten Keil 	{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
271*eac74af9SKarsten Keil 		NULL},
272*eac74af9SKarsten Keil 	{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
273*eac74af9SKarsten Keil 		NULL},
274960366cfSKarsten Keil 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
275960366cfSKarsten Keil 
276960366cfSKarsten Keil 	{TONE_GERMAN_RINGING,
277bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
278bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
279960366cfSKarsten Keil 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
280960366cfSKarsten Keil 
281960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGING,
282bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
283bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
284960366cfSKarsten Keil 	{8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
285960366cfSKarsten Keil 
286960366cfSKarsten Keil 	{TONE_AMERICAN_RINGING,
287bcf91745SHannes Eder 	{DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
288bcf91745SHannes Eder 	{SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
289960366cfSKarsten Keil 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
290960366cfSKarsten Keil 
291960366cfSKarsten Keil 	{TONE_GERMAN_RINGPBX,
292bcf91745SHannes Eder 	{DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
293bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
294960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
295960366cfSKarsten Keil 
296960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGPBX,
297bcf91745SHannes Eder 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
298bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
299960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
300960366cfSKarsten Keil 
301960366cfSKarsten Keil 	{TONE_AMERICAN_RINGPBX,
302bcf91745SHannes Eder 	{DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
303bcf91745SHannes Eder 	{SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
304960366cfSKarsten Keil 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
305960366cfSKarsten Keil 
306960366cfSKarsten Keil 	{TONE_GERMAN_BUSY,
307bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
308bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
309960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
310960366cfSKarsten Keil 
311960366cfSKarsten Keil 	{TONE_GERMAN_OLDBUSY,
312bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
313bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
314960366cfSKarsten Keil 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
315960366cfSKarsten Keil 
316960366cfSKarsten Keil 	{TONE_AMERICAN_BUSY,
317bcf91745SHannes Eder 	{DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
318bcf91745SHannes Eder 	{SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
319960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
320960366cfSKarsten Keil 
321960366cfSKarsten Keil 	{TONE_GERMAN_HANGUP,
322bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
323bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
324960366cfSKarsten Keil 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
325960366cfSKarsten Keil 
326960366cfSKarsten Keil 	{TONE_GERMAN_OLDHANGUP,
327bcf91745SHannes Eder 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
328bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
329960366cfSKarsten Keil 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
330960366cfSKarsten Keil 
331960366cfSKarsten Keil 	{TONE_AMERICAN_HANGUP,
332bcf91745SHannes Eder 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
333bcf91745SHannes Eder 	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334960366cfSKarsten Keil 	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
335960366cfSKarsten Keil 
336960366cfSKarsten Keil 	{TONE_SPECIAL_INFO,
337bcf91745SHannes Eder 	{DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
338bcf91745SHannes Eder 	{SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
339960366cfSKarsten Keil 	{2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
340960366cfSKarsten Keil 
341960366cfSKarsten Keil 	{TONE_GERMAN_GASSENBESETZT,
342bcf91745SHannes Eder 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
343bcf91745SHannes Eder 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
344960366cfSKarsten Keil 	{2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
345960366cfSKarsten Keil 
346960366cfSKarsten Keil 	{TONE_GERMAN_AUFSCHALTTON,
347bcf91745SHannes Eder 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
348bcf91745SHannes Eder 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
349960366cfSKarsten Keil 	{1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
350960366cfSKarsten Keil 
351960366cfSKarsten Keil 	{0,
352bcf91745SHannes Eder 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
353bcf91745SHannes Eder 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354960366cfSKarsten Keil 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
355960366cfSKarsten Keil };
356960366cfSKarsten Keil 
357960366cfSKarsten Keil /******************
358960366cfSKarsten Keil  * copy tone data *
359960366cfSKarsten Keil  ******************/
360960366cfSKarsten Keil 
361960366cfSKarsten Keil /* an sk_buff is generated from the number of samples needed.
362960366cfSKarsten Keil  * the count will be changed and may begin from 0 each pattern period.
363960366cfSKarsten Keil  * the clue is to precalculate the pointers and legths to use only one
364960366cfSKarsten Keil  * memcpy per function call, or two memcpy if the tone sequence changes.
365960366cfSKarsten Keil  *
366960366cfSKarsten Keil  * pattern - the type of the pattern
367960366cfSKarsten Keil  * count - the sample from the beginning of the pattern (phase)
368960366cfSKarsten Keil  * len - the number of bytes
369960366cfSKarsten Keil  *
370960366cfSKarsten Keil  * return - the sk_buff with the sample
371960366cfSKarsten Keil  *
372960366cfSKarsten Keil  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
373960366cfSKarsten Keil  */
374960366cfSKarsten Keil void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
375960366cfSKarsten Keil {
376960366cfSKarsten Keil 	int index, count, start, num;
377960366cfSKarsten Keil 	struct pattern *pat;
378960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
379960366cfSKarsten Keil 
380960366cfSKarsten Keil 	/* if we have no tone, we copy silence */
381960366cfSKarsten Keil 	if (!tone->tone) {
382960366cfSKarsten Keil 		memset(data, dsp_silence, len);
383960366cfSKarsten Keil 		return;
384960366cfSKarsten Keil 	}
385960366cfSKarsten Keil 
386960366cfSKarsten Keil 	/* process pattern */
387960366cfSKarsten Keil 	pat = (struct pattern *)tone->pattern;
388960366cfSKarsten Keil 		/* points to the current pattern */
389960366cfSKarsten Keil 	index = tone->index; /* gives current sequence index */
390960366cfSKarsten Keil 	count = tone->count; /* gives current sample */
391960366cfSKarsten Keil 
392960366cfSKarsten Keil 	/* copy sample */
393960366cfSKarsten Keil 	while (len) {
394960366cfSKarsten Keil 		/* find sample to start with */
395960366cfSKarsten Keil 		while (42) {
396960366cfSKarsten Keil 			/* warp arround */
397960366cfSKarsten Keil 			if (!pat->seq[index]) {
398960366cfSKarsten Keil 				count = 0;
399960366cfSKarsten Keil 				index = 0;
400960366cfSKarsten Keil 			}
401960366cfSKarsten Keil 			/* check if we are currently playing this tone */
402960366cfSKarsten Keil 			if (count < pat->seq[index])
403960366cfSKarsten Keil 				break;
404960366cfSKarsten Keil 			if (dsp_debug & DEBUG_DSP_TONE)
405960366cfSKarsten Keil 				printk(KERN_DEBUG "%s: reaching next sequence "
406960366cfSKarsten Keil 					"(index=%d)\n", __func__, index);
407960366cfSKarsten Keil 			count -= pat->seq[index];
408960366cfSKarsten Keil 			index++;
409960366cfSKarsten Keil 		}
410960366cfSKarsten Keil 		/* calculate start and number of samples */
411960366cfSKarsten Keil 		start = count % (*(pat->siz[index]));
412960366cfSKarsten Keil 		num = len;
413960366cfSKarsten Keil 		if (num+count > pat->seq[index])
414960366cfSKarsten Keil 			num = pat->seq[index] - count;
415960366cfSKarsten Keil 		if (num+start > (*(pat->siz[index])))
416960366cfSKarsten Keil 			num = (*(pat->siz[index])) - start;
417960366cfSKarsten Keil 		/* copy memory */
418960366cfSKarsten Keil 		memcpy(data, pat->data[index]+start, num);
419960366cfSKarsten Keil 		/* reduce length */
420960366cfSKarsten Keil 		data += num;
421960366cfSKarsten Keil 		count += num;
422960366cfSKarsten Keil 		len -= num;
423960366cfSKarsten Keil 	}
424960366cfSKarsten Keil 	tone->index = index;
425960366cfSKarsten Keil 	tone->count = count;
426960366cfSKarsten Keil 
427960366cfSKarsten Keil 	/* return sk_buff */
428960366cfSKarsten Keil 	return;
429960366cfSKarsten Keil }
430960366cfSKarsten Keil 
431960366cfSKarsten Keil 
432960366cfSKarsten Keil /*******************************
433960366cfSKarsten Keil  * send HW message to hfc card *
434960366cfSKarsten Keil  *******************************/
435960366cfSKarsten Keil 
436960366cfSKarsten Keil static void
437960366cfSKarsten Keil dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
438960366cfSKarsten Keil {
439960366cfSKarsten Keil 	struct sk_buff *nskb;
440960366cfSKarsten Keil 
441960366cfSKarsten Keil 	/* unlocking is not required, because we don't expect a response */
442960366cfSKarsten Keil 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
443960366cfSKarsten Keil 		(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
444960366cfSKarsten Keil 		GFP_ATOMIC);
445960366cfSKarsten Keil 	if (nskb) {
446960366cfSKarsten Keil 		if (dsp->ch.peer) {
447960366cfSKarsten Keil 			if (dsp->ch.recv(dsp->ch.peer, nskb))
448960366cfSKarsten Keil 				dev_kfree_skb(nskb);
449960366cfSKarsten Keil 		} else
450960366cfSKarsten Keil 			dev_kfree_skb(nskb);
451960366cfSKarsten Keil 	}
452960366cfSKarsten Keil }
453960366cfSKarsten Keil 
454960366cfSKarsten Keil 
455960366cfSKarsten Keil /*****************
456960366cfSKarsten Keil  * timer expires *
457960366cfSKarsten Keil  *****************/
458960366cfSKarsten Keil void
459960366cfSKarsten Keil dsp_tone_timeout(void *arg)
460960366cfSKarsten Keil {
461960366cfSKarsten Keil 	struct dsp *dsp = arg;
462960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
463960366cfSKarsten Keil 	struct pattern *pat = (struct pattern *)tone->pattern;
464960366cfSKarsten Keil 	int index = tone->index;
465960366cfSKarsten Keil 
466960366cfSKarsten Keil 	if (!tone->tone)
467960366cfSKarsten Keil 		return;
468960366cfSKarsten Keil 
469960366cfSKarsten Keil 	index++;
470960366cfSKarsten Keil 	if (!pat->seq[index])
471960366cfSKarsten Keil 		index = 0;
472960366cfSKarsten Keil 	tone->index = index;
473960366cfSKarsten Keil 
474960366cfSKarsten Keil 	/* set next tone */
475960366cfSKarsten Keil 	if (pat->data[index] == DATA_S)
476bcf91745SHannes Eder 		dsp_tone_hw_message(dsp, NULL, 0);
477960366cfSKarsten Keil 	else
478960366cfSKarsten Keil 		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
479960366cfSKarsten Keil 	/* set timer */
480960366cfSKarsten Keil 	init_timer(&tone->tl);
481960366cfSKarsten Keil 	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
482960366cfSKarsten Keil 	add_timer(&tone->tl);
483960366cfSKarsten Keil }
484960366cfSKarsten Keil 
485960366cfSKarsten Keil 
486960366cfSKarsten Keil /********************
487960366cfSKarsten Keil  * set/release tone *
488960366cfSKarsten Keil  ********************/
489960366cfSKarsten Keil 
490960366cfSKarsten Keil /*
491960366cfSKarsten Keil  * tones are relaized by streaming or by special loop commands if supported
492960366cfSKarsten Keil  * by hardware. when hardware is used, the patterns will be controlled by
493960366cfSKarsten Keil  * timers.
494960366cfSKarsten Keil  */
495960366cfSKarsten Keil int
496960366cfSKarsten Keil dsp_tone(struct dsp *dsp, int tone)
497960366cfSKarsten Keil {
498960366cfSKarsten Keil 	struct pattern *pat;
499960366cfSKarsten Keil 	int i;
500960366cfSKarsten Keil 	struct dsp_tone *tonet = &dsp->tone;
501960366cfSKarsten Keil 
502960366cfSKarsten Keil 	tonet->software = 0;
503960366cfSKarsten Keil 	tonet->hardware = 0;
504960366cfSKarsten Keil 
505960366cfSKarsten Keil 	/* we turn off the tone */
506960366cfSKarsten Keil 	if (!tone) {
507*eac74af9SKarsten Keil 		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
508960366cfSKarsten Keil 			del_timer(&tonet->tl);
509960366cfSKarsten Keil 		if (dsp->features.hfc_loops)
510960366cfSKarsten Keil 			dsp_tone_hw_message(dsp, NULL, 0);
511960366cfSKarsten Keil 		tonet->tone = 0;
512960366cfSKarsten Keil 		return 0;
513960366cfSKarsten Keil 	}
514960366cfSKarsten Keil 
515960366cfSKarsten Keil 	pat = NULL;
516960366cfSKarsten Keil 	i = 0;
517960366cfSKarsten Keil 	while (pattern[i].tone) {
518960366cfSKarsten Keil 		if (pattern[i].tone == tone) {
519960366cfSKarsten Keil 			pat = &pattern[i];
520960366cfSKarsten Keil 			break;
521960366cfSKarsten Keil 		}
522960366cfSKarsten Keil 		i++;
523960366cfSKarsten Keil 	}
524960366cfSKarsten Keil 	if (!pat) {
525960366cfSKarsten Keil 		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
526960366cfSKarsten Keil 		return -EINVAL;
527960366cfSKarsten Keil 	}
528960366cfSKarsten Keil 	if (dsp_debug & DEBUG_DSP_TONE)
529960366cfSKarsten Keil 		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
530960366cfSKarsten Keil 			__func__, tone, 0);
531960366cfSKarsten Keil 	tonet->tone = tone;
532960366cfSKarsten Keil 	tonet->pattern = pat;
533960366cfSKarsten Keil 	tonet->index = 0;
534960366cfSKarsten Keil 	tonet->count = 0;
535960366cfSKarsten Keil 
536960366cfSKarsten Keil 	if (dsp->features.hfc_loops) {
537960366cfSKarsten Keil 		tonet->hardware = 1;
538960366cfSKarsten Keil 		/* set first tone */
539960366cfSKarsten Keil 		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
540960366cfSKarsten Keil 		/* set timer */
541960366cfSKarsten Keil 		if (timer_pending(&tonet->tl))
542960366cfSKarsten Keil 			del_timer(&tonet->tl);
543960366cfSKarsten Keil 		init_timer(&tonet->tl);
544960366cfSKarsten Keil 		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
545960366cfSKarsten Keil 		add_timer(&tonet->tl);
546960366cfSKarsten Keil 	} else {
547960366cfSKarsten Keil 		tonet->software = 1;
548960366cfSKarsten Keil 	}
549960366cfSKarsten Keil 
550960366cfSKarsten Keil 	return 0;
551960366cfSKarsten Keil }
552960366cfSKarsten Keil 
553960366cfSKarsten Keil 
554960366cfSKarsten Keil 
555960366cfSKarsten Keil 
556960366cfSKarsten Keil 
557