xref: /linux/drivers/isdn/mISDN/dsp_tones.c (revision e313ac12eb13a9738116192848695da54c38b1ae)
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 
115a0e3ad6STejun Heo #include <linux/gfp.h>
12960366cfSKarsten Keil #include <linux/mISDNif.h>
13960366cfSKarsten Keil #include <linux/mISDNdsp.h>
14960366cfSKarsten Keil #include "core.h"
15960366cfSKarsten Keil #include "dsp.h"
16960366cfSKarsten Keil 
17960366cfSKarsten Keil 
18960366cfSKarsten Keil #define DATA_S sample_silence
19960366cfSKarsten Keil #define SIZE_S (&sizeof_silence)
20960366cfSKarsten Keil #define DATA_GA sample_german_all
21960366cfSKarsten Keil #define SIZE_GA (&sizeof_german_all)
22960366cfSKarsten Keil #define DATA_GO sample_german_old
23960366cfSKarsten Keil #define SIZE_GO (&sizeof_german_old)
24960366cfSKarsten Keil #define DATA_DT sample_american_dialtone
25960366cfSKarsten Keil #define SIZE_DT (&sizeof_american_dialtone)
26960366cfSKarsten Keil #define DATA_RI sample_american_ringing
27960366cfSKarsten Keil #define SIZE_RI (&sizeof_american_ringing)
28960366cfSKarsten Keil #define DATA_BU sample_american_busy
29960366cfSKarsten Keil #define SIZE_BU (&sizeof_american_busy)
30960366cfSKarsten Keil #define DATA_S1 sample_special1
31960366cfSKarsten Keil #define SIZE_S1 (&sizeof_special1)
32960366cfSKarsten Keil #define DATA_S2 sample_special2
33960366cfSKarsten Keil #define SIZE_S2 (&sizeof_special2)
34960366cfSKarsten Keil #define DATA_S3 sample_special3
35960366cfSKarsten Keil #define SIZE_S3 (&sizeof_special3)
36960366cfSKarsten Keil 
37960366cfSKarsten Keil /***************/
38960366cfSKarsten Keil /* tones loops */
39960366cfSKarsten Keil /***************/
40960366cfSKarsten Keil 
41960366cfSKarsten Keil /* all tones are alaw encoded */
42960366cfSKarsten Keil /* the last sample+1 is in phase with the first sample. the error is low */
43960366cfSKarsten Keil 
44960366cfSKarsten Keil static u8 sample_german_all[] = {
45960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
46960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
47960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
48960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
49960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
50960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
51960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
52960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
53960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
54960366cfSKarsten Keil 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
55960366cfSKarsten Keil 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
56960366cfSKarsten Keil 	0xdc, 0xfc, 0x6c,
57960366cfSKarsten Keil };
58960366cfSKarsten Keil static u32 sizeof_german_all = sizeof(sample_german_all);
59960366cfSKarsten Keil 
60960366cfSKarsten Keil static u8 sample_german_old[] = {
61960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
62960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
63960366cfSKarsten Keil 	0x8c,
64960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
65960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
66960366cfSKarsten Keil 	0x8c,
67960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
68960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
69960366cfSKarsten Keil 	0x8c,
70960366cfSKarsten Keil 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
71960366cfSKarsten Keil 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
72960366cfSKarsten Keil 	0x8c,
73960366cfSKarsten Keil };
74960366cfSKarsten Keil static u32 sizeof_german_old = sizeof(sample_german_old);
75960366cfSKarsten Keil 
76960366cfSKarsten Keil static u8 sample_american_dialtone[] = {
77960366cfSKarsten Keil 	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
78960366cfSKarsten Keil 	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
79960366cfSKarsten Keil 	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
80960366cfSKarsten Keil 	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
81960366cfSKarsten Keil 	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
82960366cfSKarsten Keil 	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
83960366cfSKarsten Keil 	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
84960366cfSKarsten Keil 	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
85960366cfSKarsten Keil 	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
86960366cfSKarsten Keil 	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
87960366cfSKarsten Keil 	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
88960366cfSKarsten Keil 	0x6d, 0x91, 0x19,
89960366cfSKarsten Keil };
90960366cfSKarsten Keil static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
91960366cfSKarsten Keil 
92960366cfSKarsten Keil static u8 sample_american_ringing[] = {
93960366cfSKarsten Keil 	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
94960366cfSKarsten Keil 	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
95960366cfSKarsten Keil 	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
96960366cfSKarsten Keil 	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
97960366cfSKarsten Keil 	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
98960366cfSKarsten Keil 	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
99960366cfSKarsten Keil 	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
100960366cfSKarsten Keil 	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
101960366cfSKarsten Keil 	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
102960366cfSKarsten Keil 	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
103960366cfSKarsten Keil 	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
104960366cfSKarsten Keil 	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
105960366cfSKarsten Keil 	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
106960366cfSKarsten Keil 	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
107960366cfSKarsten Keil 	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
108960366cfSKarsten Keil 	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
109960366cfSKarsten Keil 	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
110960366cfSKarsten Keil 	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
111960366cfSKarsten Keil 	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
112960366cfSKarsten Keil 	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
113960366cfSKarsten Keil 	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
114960366cfSKarsten Keil };
115960366cfSKarsten Keil static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
116960366cfSKarsten Keil 
117960366cfSKarsten Keil static u8 sample_american_busy[] = {
118960366cfSKarsten Keil 	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
119960366cfSKarsten Keil 	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
120960366cfSKarsten Keil 	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
121960366cfSKarsten Keil 	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
122960366cfSKarsten Keil 	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
123960366cfSKarsten Keil 	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
124960366cfSKarsten Keil 	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
125960366cfSKarsten Keil 	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
126960366cfSKarsten Keil 	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
127960366cfSKarsten Keil 	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
128960366cfSKarsten Keil 	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
129960366cfSKarsten Keil 	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
130960366cfSKarsten Keil 	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
131960366cfSKarsten Keil 	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
132960366cfSKarsten Keil 	0x4d, 0x4d, 0x6d, 0x01,
133960366cfSKarsten Keil };
134960366cfSKarsten Keil static u32 sizeof_american_busy = sizeof(sample_american_busy);
135960366cfSKarsten Keil 
136960366cfSKarsten Keil static u8 sample_special1[] = {
137960366cfSKarsten Keil 	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
138960366cfSKarsten Keil 	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
139960366cfSKarsten Keil 	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
140960366cfSKarsten Keil 	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
141960366cfSKarsten Keil 	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
142960366cfSKarsten Keil 	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
143960366cfSKarsten Keil 	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
144960366cfSKarsten Keil 	0x6d, 0xbd, 0x2d,
145960366cfSKarsten Keil };
146960366cfSKarsten Keil static u32 sizeof_special1 = sizeof(sample_special1);
147960366cfSKarsten Keil 
148960366cfSKarsten Keil static u8 sample_special2[] = {
149960366cfSKarsten Keil 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
150960366cfSKarsten Keil 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
151960366cfSKarsten Keil 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
152960366cfSKarsten Keil 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
153960366cfSKarsten Keil 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
154960366cfSKarsten Keil 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
155960366cfSKarsten Keil 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
156960366cfSKarsten Keil 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
157960366cfSKarsten Keil 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
158960366cfSKarsten Keil 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
159960366cfSKarsten Keil };
160960366cfSKarsten Keil static u32 sizeof_special2 = sizeof(sample_special2);
161960366cfSKarsten Keil 
162960366cfSKarsten Keil static u8 sample_special3[] = {
163960366cfSKarsten Keil 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
164960366cfSKarsten Keil 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
165960366cfSKarsten Keil 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
166960366cfSKarsten Keil 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
167960366cfSKarsten Keil 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
168960366cfSKarsten Keil 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
169960366cfSKarsten Keil 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
170960366cfSKarsten Keil 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
171960366cfSKarsten Keil 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
172960366cfSKarsten Keil 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
173960366cfSKarsten Keil };
174960366cfSKarsten Keil static u32 sizeof_special3 = sizeof(sample_special3);
175960366cfSKarsten Keil 
176960366cfSKarsten Keil static u8 sample_silence[] = {
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 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
189960366cfSKarsten Keil };
190960366cfSKarsten Keil static u32 sizeof_silence = sizeof(sample_silence);
191960366cfSKarsten Keil 
192960366cfSKarsten Keil struct tones_samples {
193960366cfSKarsten Keil 	u32 *len;
194960366cfSKarsten Keil 	u8 *data;
195960366cfSKarsten Keil };
196960366cfSKarsten Keil static struct
197960366cfSKarsten Keil tones_samples samples[] = {
198960366cfSKarsten Keil 	{&sizeof_german_all, sample_german_all},
199960366cfSKarsten Keil 	{&sizeof_german_old, sample_german_old},
200960366cfSKarsten Keil 	{&sizeof_american_dialtone, sample_american_dialtone},
201960366cfSKarsten Keil 	{&sizeof_american_ringing, sample_american_ringing},
202960366cfSKarsten Keil 	{&sizeof_american_busy, sample_american_busy},
203960366cfSKarsten Keil 	{&sizeof_special1, sample_special1},
204960366cfSKarsten Keil 	{&sizeof_special2, sample_special2},
205960366cfSKarsten Keil 	{&sizeof_special3, sample_special3},
206960366cfSKarsten Keil 	{NULL, NULL},
207960366cfSKarsten Keil };
208960366cfSKarsten Keil 
209960366cfSKarsten Keil /***********************************
210960366cfSKarsten Keil  * generate ulaw from alaw samples *
211960366cfSKarsten Keil  ***********************************/
212960366cfSKarsten Keil 
213960366cfSKarsten Keil void
214960366cfSKarsten Keil dsp_audio_generate_ulaw_samples(void)
215960366cfSKarsten Keil {
216960366cfSKarsten Keil 	int i, j;
217960366cfSKarsten Keil 
218960366cfSKarsten Keil 	i = 0;
219960366cfSKarsten Keil 	while (samples[i].len) {
220960366cfSKarsten Keil 		j = 0;
221960366cfSKarsten Keil 		while (j < (*samples[i].len)) {
222960366cfSKarsten Keil 			samples[i].data[j] =
223960366cfSKarsten Keil 				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
224960366cfSKarsten Keil 			j++;
225960366cfSKarsten Keil 		}
226960366cfSKarsten Keil 		i++;
227960366cfSKarsten Keil 	}
228960366cfSKarsten Keil }
229960366cfSKarsten Keil 
230960366cfSKarsten Keil 
231960366cfSKarsten Keil /****************************
232960366cfSKarsten Keil  * tone sequence definition *
233960366cfSKarsten Keil  ****************************/
234960366cfSKarsten Keil 
2355b834354SHannes Eder static struct pattern {
236960366cfSKarsten Keil 	int tone;
237960366cfSKarsten Keil 	u8 *data[10];
238960366cfSKarsten Keil 	u32 *siz[10];
239960366cfSKarsten Keil 	u32 seq[10];
240960366cfSKarsten Keil } pattern[] = {
241960366cfSKarsten Keil 	{TONE_GERMAN_DIALTONE,
242bcf91745SHannes Eder 	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243bcf91745SHannes Eder 	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
244960366cfSKarsten Keil 	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
245960366cfSKarsten Keil 
246960366cfSKarsten Keil 	{TONE_GERMAN_OLDDIALTONE,
247bcf91745SHannes Eder 	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248bcf91745SHannes Eder 	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
249960366cfSKarsten Keil 	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
250960366cfSKarsten Keil 
251960366cfSKarsten Keil 	{TONE_AMERICAN_DIALTONE,
252bcf91745SHannes Eder 	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253bcf91745SHannes Eder 	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
254960366cfSKarsten Keil 	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
255960366cfSKarsten Keil 
256960366cfSKarsten Keil 	{TONE_GERMAN_DIALPBX,
257eac74af9SKarsten Keil 	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
258eac74af9SKarsten Keil 	  NULL},
259eac74af9SKarsten Keil 	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
260eac74af9SKarsten Keil 	  NULL},
261960366cfSKarsten Keil 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262960366cfSKarsten Keil 
263960366cfSKarsten Keil 	{TONE_GERMAN_OLDDIALPBX,
264eac74af9SKarsten Keil 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
265eac74af9SKarsten Keil 	  NULL},
266eac74af9SKarsten Keil 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
267eac74af9SKarsten Keil 	  NULL},
268960366cfSKarsten Keil 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269960366cfSKarsten Keil 
270960366cfSKarsten Keil 	{TONE_AMERICAN_DIALPBX,
271eac74af9SKarsten Keil 	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
272eac74af9SKarsten Keil 	  NULL},
273eac74af9SKarsten Keil 	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
274eac74af9SKarsten Keil 	  NULL},
275960366cfSKarsten Keil 	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276960366cfSKarsten Keil 
277960366cfSKarsten Keil 	{TONE_GERMAN_RINGING,
278bcf91745SHannes Eder 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
279bcf91745SHannes Eder 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
280960366cfSKarsten Keil 	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
281960366cfSKarsten Keil 
282960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGING,
283bcf91745SHannes Eder 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
284bcf91745SHannes Eder 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
285960366cfSKarsten Keil 	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
286960366cfSKarsten Keil 
287960366cfSKarsten Keil 	{TONE_AMERICAN_RINGING,
288bcf91745SHannes Eder 	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
289bcf91745SHannes Eder 	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
290960366cfSKarsten Keil 	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
291960366cfSKarsten Keil 
292960366cfSKarsten Keil 	{TONE_GERMAN_RINGPBX,
293bcf91745SHannes Eder 	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
294bcf91745SHannes Eder 	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
295960366cfSKarsten Keil 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
296960366cfSKarsten Keil 
297960366cfSKarsten Keil 	{TONE_GERMAN_OLDRINGPBX,
298bcf91745SHannes Eder 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
299bcf91745SHannes Eder 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
300960366cfSKarsten Keil 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
301960366cfSKarsten Keil 
302960366cfSKarsten Keil 	{TONE_AMERICAN_RINGPBX,
303bcf91745SHannes Eder 	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
304bcf91745SHannes Eder 	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
305960366cfSKarsten Keil 	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
306960366cfSKarsten Keil 
307960366cfSKarsten Keil 	{TONE_GERMAN_BUSY,
308bcf91745SHannes Eder 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
309bcf91745SHannes Eder 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
310960366cfSKarsten Keil 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
311960366cfSKarsten Keil 
312960366cfSKarsten Keil 	{TONE_GERMAN_OLDBUSY,
313bcf91745SHannes Eder 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
314bcf91745SHannes Eder 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
315960366cfSKarsten Keil 	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
316960366cfSKarsten Keil 
317960366cfSKarsten Keil 	{TONE_AMERICAN_BUSY,
318bcf91745SHannes Eder 	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
319bcf91745SHannes Eder 	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
320960366cfSKarsten Keil 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
321960366cfSKarsten Keil 
322960366cfSKarsten Keil 	{TONE_GERMAN_HANGUP,
323bcf91745SHannes Eder 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
324bcf91745SHannes Eder 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
325960366cfSKarsten Keil 	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
326960366cfSKarsten Keil 
327960366cfSKarsten Keil 	{TONE_GERMAN_OLDHANGUP,
328bcf91745SHannes Eder 	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
329bcf91745SHannes Eder 	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
330960366cfSKarsten Keil 	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
331960366cfSKarsten Keil 
332960366cfSKarsten Keil 	{TONE_AMERICAN_HANGUP,
333bcf91745SHannes Eder 	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334bcf91745SHannes Eder 	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
335960366cfSKarsten Keil 	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
336960366cfSKarsten Keil 
337960366cfSKarsten Keil 	{TONE_SPECIAL_INFO,
338bcf91745SHannes Eder 	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
339bcf91745SHannes Eder 	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
340960366cfSKarsten Keil 	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
341960366cfSKarsten Keil 
342960366cfSKarsten Keil 	{TONE_GERMAN_GASSENBESETZT,
343bcf91745SHannes Eder 	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
344bcf91745SHannes Eder 	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
345960366cfSKarsten Keil 	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
346960366cfSKarsten Keil 
347960366cfSKarsten Keil 	{TONE_GERMAN_AUFSCHALTTON,
348bcf91745SHannes Eder 	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
349bcf91745SHannes Eder 	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
350960366cfSKarsten Keil 	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
351960366cfSKarsten Keil 
352960366cfSKarsten Keil 	{0,
353bcf91745SHannes Eder 	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354bcf91745SHannes Eder 	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
355960366cfSKarsten Keil 	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
356960366cfSKarsten Keil };
357960366cfSKarsten Keil 
358960366cfSKarsten Keil /******************
359960366cfSKarsten Keil  * copy tone data *
360960366cfSKarsten Keil  ******************/
361960366cfSKarsten Keil 
362960366cfSKarsten Keil /* an sk_buff is generated from the number of samples needed.
363960366cfSKarsten Keil  * the count will be changed and may begin from 0 each pattern period.
364960366cfSKarsten Keil  * the clue is to precalculate the pointers and legths to use only one
365960366cfSKarsten Keil  * memcpy per function call, or two memcpy if the tone sequence changes.
366960366cfSKarsten Keil  *
367960366cfSKarsten Keil  * pattern - the type of the pattern
368960366cfSKarsten Keil  * count - the sample from the beginning of the pattern (phase)
369960366cfSKarsten Keil  * len - the number of bytes
370960366cfSKarsten Keil  *
371960366cfSKarsten Keil  * return - the sk_buff with the sample
372960366cfSKarsten Keil  *
373960366cfSKarsten Keil  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
374960366cfSKarsten Keil  */
375960366cfSKarsten Keil void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
376960366cfSKarsten Keil {
377960366cfSKarsten Keil 	int index, count, start, num;
378960366cfSKarsten Keil 	struct pattern *pat;
379960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
380960366cfSKarsten Keil 
381960366cfSKarsten Keil 	/* if we have no tone, we copy silence */
382960366cfSKarsten Keil 	if (!tone->tone) {
383960366cfSKarsten Keil 		memset(data, dsp_silence, len);
384960366cfSKarsten Keil 		return;
385960366cfSKarsten Keil 	}
386960366cfSKarsten Keil 
387960366cfSKarsten Keil 	/* process pattern */
388960366cfSKarsten Keil 	pat = (struct pattern *)tone->pattern;
389960366cfSKarsten Keil 	/* points to the current pattern */
390960366cfSKarsten Keil 	index = tone->index; /* gives current sequence index */
391960366cfSKarsten Keil 	count = tone->count; /* gives current sample */
392960366cfSKarsten Keil 
393960366cfSKarsten Keil 	/* copy sample */
394960366cfSKarsten Keil 	while (len) {
395960366cfSKarsten Keil 		/* find sample to start with */
396960366cfSKarsten Keil 		while (42) {
39725985edcSLucas De Marchi 			/* wrap around */
398960366cfSKarsten Keil 			if (!pat->seq[index]) {
399960366cfSKarsten Keil 				count = 0;
400960366cfSKarsten Keil 				index = 0;
401960366cfSKarsten Keil 			}
402960366cfSKarsten Keil 			/* check if we are currently playing this tone */
403960366cfSKarsten Keil 			if (count < pat->seq[index])
404960366cfSKarsten Keil 				break;
405960366cfSKarsten Keil 			if (dsp_debug & DEBUG_DSP_TONE)
406960366cfSKarsten Keil 				printk(KERN_DEBUG "%s: reaching next sequence "
407960366cfSKarsten Keil 				       "(index=%d)\n", __func__, index);
408960366cfSKarsten Keil 			count -= pat->seq[index];
409960366cfSKarsten Keil 			index++;
410960366cfSKarsten Keil 		}
411960366cfSKarsten Keil 		/* calculate start and number of samples */
412960366cfSKarsten Keil 		start = count % (*(pat->siz[index]));
413960366cfSKarsten Keil 		num = len;
414960366cfSKarsten Keil 		if (num + count > pat->seq[index])
415960366cfSKarsten Keil 			num = pat->seq[index] - count;
416960366cfSKarsten Keil 		if (num + start > (*(pat->siz[index])))
417960366cfSKarsten Keil 			num = (*(pat->siz[index])) - start;
418960366cfSKarsten Keil 		/* copy memory */
419960366cfSKarsten Keil 		memcpy(data, pat->data[index] + start, num);
420960366cfSKarsten Keil 		/* reduce length */
421960366cfSKarsten Keil 		data += num;
422960366cfSKarsten Keil 		count += num;
423960366cfSKarsten Keil 		len -= num;
424960366cfSKarsten Keil 	}
425960366cfSKarsten Keil 	tone->index = index;
426960366cfSKarsten Keil 	tone->count = count;
427960366cfSKarsten Keil 
428960366cfSKarsten Keil 	/* return sk_buff */
429960366cfSKarsten Keil 	return;
430960366cfSKarsten Keil }
431960366cfSKarsten Keil 
432960366cfSKarsten Keil 
433960366cfSKarsten Keil /*******************************
434960366cfSKarsten Keil  * send HW message to hfc card *
435960366cfSKarsten Keil  *******************************/
436960366cfSKarsten Keil 
437960366cfSKarsten Keil static void
438960366cfSKarsten Keil dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
439960366cfSKarsten Keil {
440960366cfSKarsten Keil 	struct sk_buff *nskb;
441960366cfSKarsten Keil 
442960366cfSKarsten Keil 	/* unlocking is not required, because we don't expect a response */
443960366cfSKarsten Keil 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
444960366cfSKarsten Keil 				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
445960366cfSKarsten Keil 				GFP_ATOMIC);
446960366cfSKarsten Keil 	if (nskb) {
447960366cfSKarsten Keil 		if (dsp->ch.peer) {
448960366cfSKarsten Keil 			if (dsp->ch.recv(dsp->ch.peer, nskb))
449960366cfSKarsten Keil 				dev_kfree_skb(nskb);
450960366cfSKarsten Keil 		} else
451960366cfSKarsten Keil 			dev_kfree_skb(nskb);
452960366cfSKarsten Keil 	}
453960366cfSKarsten Keil }
454960366cfSKarsten Keil 
455960366cfSKarsten Keil 
456960366cfSKarsten Keil /*****************
457960366cfSKarsten Keil  * timer expires *
458960366cfSKarsten Keil  *****************/
459960366cfSKarsten Keil void
460*e313ac12SKees Cook dsp_tone_timeout(struct timer_list *t)
461960366cfSKarsten Keil {
462*e313ac12SKees Cook 	struct dsp *dsp = from_timer(dsp, t, tone.tl);
463960366cfSKarsten Keil 	struct dsp_tone *tone = &dsp->tone;
464960366cfSKarsten Keil 	struct pattern *pat = (struct pattern *)tone->pattern;
465960366cfSKarsten Keil 	int index = tone->index;
466960366cfSKarsten Keil 
467960366cfSKarsten Keil 	if (!tone->tone)
468960366cfSKarsten Keil 		return;
469960366cfSKarsten Keil 
470960366cfSKarsten Keil 	index++;
471960366cfSKarsten Keil 	if (!pat->seq[index])
472960366cfSKarsten Keil 		index = 0;
473960366cfSKarsten Keil 	tone->index = index;
474960366cfSKarsten Keil 
475960366cfSKarsten Keil 	/* set next tone */
476960366cfSKarsten Keil 	if (pat->data[index] == DATA_S)
477bcf91745SHannes Eder 		dsp_tone_hw_message(dsp, NULL, 0);
478960366cfSKarsten Keil 	else
479960366cfSKarsten Keil 		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
480960366cfSKarsten Keil 	/* set timer */
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) {
507eac74af9SKarsten 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 		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
544960366cfSKarsten Keil 		add_timer(&tonet->tl);
545960366cfSKarsten Keil 	} else {
546960366cfSKarsten Keil 		tonet->software = 1;
547960366cfSKarsten Keil 	}
548960366cfSKarsten Keil 
549960366cfSKarsten Keil 	return 0;
550960366cfSKarsten Keil }
551