162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Audio support data for ISDN4Linux.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright Andreas Eversberg (jolly@eversberg.eu)
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software may be used and distributed according to the terms
762306a36Sopenharmony_ci * of the GNU General Public License, incorporated herein by reference.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/gfp.h>
1262306a36Sopenharmony_ci#include <linux/mISDNif.h>
1362306a36Sopenharmony_ci#include <linux/mISDNdsp.h>
1462306a36Sopenharmony_ci#include "core.h"
1562306a36Sopenharmony_ci#include "dsp.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define DATA_S sample_silence
1962306a36Sopenharmony_ci#define SIZE_S (&sizeof_silence)
2062306a36Sopenharmony_ci#define DATA_GA sample_german_all
2162306a36Sopenharmony_ci#define SIZE_GA (&sizeof_german_all)
2262306a36Sopenharmony_ci#define DATA_GO sample_german_old
2362306a36Sopenharmony_ci#define SIZE_GO (&sizeof_german_old)
2462306a36Sopenharmony_ci#define DATA_DT sample_american_dialtone
2562306a36Sopenharmony_ci#define SIZE_DT (&sizeof_american_dialtone)
2662306a36Sopenharmony_ci#define DATA_RI sample_american_ringing
2762306a36Sopenharmony_ci#define SIZE_RI (&sizeof_american_ringing)
2862306a36Sopenharmony_ci#define DATA_BU sample_american_busy
2962306a36Sopenharmony_ci#define SIZE_BU (&sizeof_american_busy)
3062306a36Sopenharmony_ci#define DATA_S1 sample_special1
3162306a36Sopenharmony_ci#define SIZE_S1 (&sizeof_special1)
3262306a36Sopenharmony_ci#define DATA_S2 sample_special2
3362306a36Sopenharmony_ci#define SIZE_S2 (&sizeof_special2)
3462306a36Sopenharmony_ci#define DATA_S3 sample_special3
3562306a36Sopenharmony_ci#define SIZE_S3 (&sizeof_special3)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/***************/
3862306a36Sopenharmony_ci/* tones loops */
3962306a36Sopenharmony_ci/***************/
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* all tones are alaw encoded */
4262306a36Sopenharmony_ci/* the last sample+1 is in phase with the first sample. the error is low */
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic u8 sample_german_all[] = {
4562306a36Sopenharmony_ci	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
4662306a36Sopenharmony_ci	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
4762306a36Sopenharmony_ci	0xdc, 0xfc, 0x6c,
4862306a36Sopenharmony_ci	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
4962306a36Sopenharmony_ci	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
5062306a36Sopenharmony_ci	0xdc, 0xfc, 0x6c,
5162306a36Sopenharmony_ci	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
5262306a36Sopenharmony_ci	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
5362306a36Sopenharmony_ci	0xdc, 0xfc, 0x6c,
5462306a36Sopenharmony_ci	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
5562306a36Sopenharmony_ci	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
5662306a36Sopenharmony_ci	0xdc, 0xfc, 0x6c,
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_cistatic u32 sizeof_german_all = sizeof(sample_german_all);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic u8 sample_german_old[] = {
6162306a36Sopenharmony_ci	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
6262306a36Sopenharmony_ci	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
6362306a36Sopenharmony_ci	0x8c,
6462306a36Sopenharmony_ci	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
6562306a36Sopenharmony_ci	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
6662306a36Sopenharmony_ci	0x8c,
6762306a36Sopenharmony_ci	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
6862306a36Sopenharmony_ci	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
6962306a36Sopenharmony_ci	0x8c,
7062306a36Sopenharmony_ci	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
7162306a36Sopenharmony_ci	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
7262306a36Sopenharmony_ci	0x8c,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_cistatic u32 sizeof_german_old = sizeof(sample_german_old);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistatic u8 sample_american_dialtone[] = {
7762306a36Sopenharmony_ci	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
7862306a36Sopenharmony_ci	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
7962306a36Sopenharmony_ci	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
8062306a36Sopenharmony_ci	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
8162306a36Sopenharmony_ci	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
8262306a36Sopenharmony_ci	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
8362306a36Sopenharmony_ci	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
8462306a36Sopenharmony_ci	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
8562306a36Sopenharmony_ci	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
8662306a36Sopenharmony_ci	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
8762306a36Sopenharmony_ci	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
8862306a36Sopenharmony_ci	0x6d, 0x91, 0x19,
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_cistatic u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic u8 sample_american_ringing[] = {
9362306a36Sopenharmony_ci	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
9462306a36Sopenharmony_ci	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
9562306a36Sopenharmony_ci	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
9662306a36Sopenharmony_ci	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
9762306a36Sopenharmony_ci	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
9862306a36Sopenharmony_ci	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
9962306a36Sopenharmony_ci	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
10062306a36Sopenharmony_ci	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
10162306a36Sopenharmony_ci	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
10262306a36Sopenharmony_ci	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
10362306a36Sopenharmony_ci	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
10462306a36Sopenharmony_ci	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
10562306a36Sopenharmony_ci	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
10662306a36Sopenharmony_ci	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
10762306a36Sopenharmony_ci	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
10862306a36Sopenharmony_ci	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
10962306a36Sopenharmony_ci	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
11062306a36Sopenharmony_ci	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
11162306a36Sopenharmony_ci	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
11262306a36Sopenharmony_ci	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
11362306a36Sopenharmony_ci	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
11462306a36Sopenharmony_ci};
11562306a36Sopenharmony_cistatic u32 sizeof_american_ringing = sizeof(sample_american_ringing);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic u8 sample_american_busy[] = {
11862306a36Sopenharmony_ci	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
11962306a36Sopenharmony_ci	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
12062306a36Sopenharmony_ci	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
12162306a36Sopenharmony_ci	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
12262306a36Sopenharmony_ci	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
12362306a36Sopenharmony_ci	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
12462306a36Sopenharmony_ci	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
12562306a36Sopenharmony_ci	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
12662306a36Sopenharmony_ci	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
12762306a36Sopenharmony_ci	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
12862306a36Sopenharmony_ci	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
12962306a36Sopenharmony_ci	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
13062306a36Sopenharmony_ci	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
13162306a36Sopenharmony_ci	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
13262306a36Sopenharmony_ci	0x4d, 0x4d, 0x6d, 0x01,
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_cistatic u32 sizeof_american_busy = sizeof(sample_american_busy);
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic u8 sample_special1[] = {
13762306a36Sopenharmony_ci	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
13862306a36Sopenharmony_ci	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
13962306a36Sopenharmony_ci	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
14062306a36Sopenharmony_ci	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
14162306a36Sopenharmony_ci	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
14262306a36Sopenharmony_ci	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
14362306a36Sopenharmony_ci	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
14462306a36Sopenharmony_ci	0x6d, 0xbd, 0x2d,
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_cistatic u32 sizeof_special1 = sizeof(sample_special1);
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cistatic u8 sample_special2[] = {
14962306a36Sopenharmony_ci	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
15062306a36Sopenharmony_ci	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
15162306a36Sopenharmony_ci	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
15262306a36Sopenharmony_ci	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
15362306a36Sopenharmony_ci	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
15462306a36Sopenharmony_ci	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
15562306a36Sopenharmony_ci	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
15662306a36Sopenharmony_ci	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
15762306a36Sopenharmony_ci	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
15862306a36Sopenharmony_ci	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
15962306a36Sopenharmony_ci};
16062306a36Sopenharmony_cistatic u32 sizeof_special2 = sizeof(sample_special2);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic u8 sample_special3[] = {
16362306a36Sopenharmony_ci	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
16462306a36Sopenharmony_ci	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
16562306a36Sopenharmony_ci	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
16662306a36Sopenharmony_ci	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
16762306a36Sopenharmony_ci	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
16862306a36Sopenharmony_ci	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
16962306a36Sopenharmony_ci	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
17062306a36Sopenharmony_ci	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
17162306a36Sopenharmony_ci	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
17262306a36Sopenharmony_ci	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
17362306a36Sopenharmony_ci};
17462306a36Sopenharmony_cistatic u32 sizeof_special3 = sizeof(sample_special3);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic u8 sample_silence[] = {
17762306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
17862306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
17962306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18062306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18162306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18262306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18362306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18462306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18562306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18662306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18762306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18862306a36Sopenharmony_ci	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_cistatic u32 sizeof_silence = sizeof(sample_silence);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistruct tones_samples {
19362306a36Sopenharmony_ci	u32 *len;
19462306a36Sopenharmony_ci	u8 *data;
19562306a36Sopenharmony_ci};
19662306a36Sopenharmony_cistatic struct
19762306a36Sopenharmony_citones_samples samples[] = {
19862306a36Sopenharmony_ci	{&sizeof_german_all, sample_german_all},
19962306a36Sopenharmony_ci	{&sizeof_german_old, sample_german_old},
20062306a36Sopenharmony_ci	{&sizeof_american_dialtone, sample_american_dialtone},
20162306a36Sopenharmony_ci	{&sizeof_american_ringing, sample_american_ringing},
20262306a36Sopenharmony_ci	{&sizeof_american_busy, sample_american_busy},
20362306a36Sopenharmony_ci	{&sizeof_special1, sample_special1},
20462306a36Sopenharmony_ci	{&sizeof_special2, sample_special2},
20562306a36Sopenharmony_ci	{&sizeof_special3, sample_special3},
20662306a36Sopenharmony_ci	{NULL, NULL},
20762306a36Sopenharmony_ci};
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/***********************************
21062306a36Sopenharmony_ci * generate ulaw from alaw samples *
21162306a36Sopenharmony_ci ***********************************/
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_civoid
21462306a36Sopenharmony_cidsp_audio_generate_ulaw_samples(void)
21562306a36Sopenharmony_ci{
21662306a36Sopenharmony_ci	int i, j;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	i = 0;
21962306a36Sopenharmony_ci	while (samples[i].len) {
22062306a36Sopenharmony_ci		j = 0;
22162306a36Sopenharmony_ci		while (j < (*samples[i].len)) {
22262306a36Sopenharmony_ci			samples[i].data[j] =
22362306a36Sopenharmony_ci				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
22462306a36Sopenharmony_ci			j++;
22562306a36Sopenharmony_ci		}
22662306a36Sopenharmony_ci		i++;
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/****************************
23262306a36Sopenharmony_ci * tone sequence definition *
23362306a36Sopenharmony_ci ****************************/
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic struct pattern {
23662306a36Sopenharmony_ci	int tone;
23762306a36Sopenharmony_ci	u8 *data[10];
23862306a36Sopenharmony_ci	u32 *siz[10];
23962306a36Sopenharmony_ci	u32 seq[10];
24062306a36Sopenharmony_ci} pattern[] = {
24162306a36Sopenharmony_ci	{TONE_GERMAN_DIALTONE,
24262306a36Sopenharmony_ci	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
24362306a36Sopenharmony_ci	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
24462306a36Sopenharmony_ci	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	{TONE_GERMAN_OLDDIALTONE,
24762306a36Sopenharmony_ci	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
24862306a36Sopenharmony_ci	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
24962306a36Sopenharmony_ci	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	{TONE_AMERICAN_DIALTONE,
25262306a36Sopenharmony_ci	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
25362306a36Sopenharmony_ci	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
25462306a36Sopenharmony_ci	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	{TONE_GERMAN_DIALPBX,
25762306a36Sopenharmony_ci	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
25862306a36Sopenharmony_ci	  NULL},
25962306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
26062306a36Sopenharmony_ci	  NULL},
26162306a36Sopenharmony_ci	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	{TONE_GERMAN_OLDDIALPBX,
26462306a36Sopenharmony_ci	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
26562306a36Sopenharmony_ci	  NULL},
26662306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
26762306a36Sopenharmony_ci	  NULL},
26862306a36Sopenharmony_ci	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	{TONE_AMERICAN_DIALPBX,
27162306a36Sopenharmony_ci	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
27262306a36Sopenharmony_ci	  NULL},
27362306a36Sopenharmony_ci	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
27462306a36Sopenharmony_ci	  NULL},
27562306a36Sopenharmony_ci	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	{TONE_GERMAN_RINGING,
27862306a36Sopenharmony_ci	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
27962306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
28062306a36Sopenharmony_ci	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	{TONE_GERMAN_OLDRINGING,
28362306a36Sopenharmony_ci	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
28462306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
28562306a36Sopenharmony_ci	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	{TONE_AMERICAN_RINGING,
28862306a36Sopenharmony_ci	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
28962306a36Sopenharmony_ci	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
29062306a36Sopenharmony_ci	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	{TONE_GERMAN_RINGPBX,
29362306a36Sopenharmony_ci	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
29462306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
29562306a36Sopenharmony_ci	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	{TONE_GERMAN_OLDRINGPBX,
29862306a36Sopenharmony_ci	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
29962306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
30062306a36Sopenharmony_ci	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	{TONE_AMERICAN_RINGPBX,
30362306a36Sopenharmony_ci	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
30462306a36Sopenharmony_ci	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
30562306a36Sopenharmony_ci	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	{TONE_GERMAN_BUSY,
30862306a36Sopenharmony_ci	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
30962306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
31062306a36Sopenharmony_ci	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	{TONE_GERMAN_OLDBUSY,
31362306a36Sopenharmony_ci	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
31462306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
31562306a36Sopenharmony_ci	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	{TONE_AMERICAN_BUSY,
31862306a36Sopenharmony_ci	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
31962306a36Sopenharmony_ci	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
32062306a36Sopenharmony_ci	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	{TONE_GERMAN_HANGUP,
32362306a36Sopenharmony_ci	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
32462306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
32562306a36Sopenharmony_ci	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	{TONE_GERMAN_OLDHANGUP,
32862306a36Sopenharmony_ci	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
32962306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
33062306a36Sopenharmony_ci	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	{TONE_AMERICAN_HANGUP,
33362306a36Sopenharmony_ci	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
33462306a36Sopenharmony_ci	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
33562306a36Sopenharmony_ci	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	{TONE_SPECIAL_INFO,
33862306a36Sopenharmony_ci	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
33962306a36Sopenharmony_ci	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
34062306a36Sopenharmony_ci	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	{TONE_GERMAN_GASSENBESETZT,
34362306a36Sopenharmony_ci	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
34462306a36Sopenharmony_ci	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
34562306a36Sopenharmony_ci	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	{TONE_GERMAN_AUFSCHALTTON,
34862306a36Sopenharmony_ci	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
34962306a36Sopenharmony_ci	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
35062306a36Sopenharmony_ci	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	{0,
35362306a36Sopenharmony_ci	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
35462306a36Sopenharmony_ci	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
35562306a36Sopenharmony_ci	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
35662306a36Sopenharmony_ci};
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci/******************
35962306a36Sopenharmony_ci * copy tone data *
36062306a36Sopenharmony_ci ******************/
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci/* an sk_buff is generated from the number of samples needed.
36362306a36Sopenharmony_ci * the count will be changed and may begin from 0 each pattern period.
36462306a36Sopenharmony_ci * the clue is to precalculate the pointers and legths to use only one
36562306a36Sopenharmony_ci * memcpy per function call, or two memcpy if the tone sequence changes.
36662306a36Sopenharmony_ci *
36762306a36Sopenharmony_ci * pattern - the type of the pattern
36862306a36Sopenharmony_ci * count - the sample from the beginning of the pattern (phase)
36962306a36Sopenharmony_ci * len - the number of bytes
37062306a36Sopenharmony_ci *
37162306a36Sopenharmony_ci * return - the sk_buff with the sample
37262306a36Sopenharmony_ci *
37362306a36Sopenharmony_ci * if tones has finished (e.g. knocking tone), dsp->tones is turned off
37462306a36Sopenharmony_ci */
37562306a36Sopenharmony_civoid dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	int index, count, start, num;
37862306a36Sopenharmony_ci	struct pattern *pat;
37962306a36Sopenharmony_ci	struct dsp_tone *tone = &dsp->tone;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	/* if we have no tone, we copy silence */
38262306a36Sopenharmony_ci	if (!tone->tone) {
38362306a36Sopenharmony_ci		memset(data, dsp_silence, len);
38462306a36Sopenharmony_ci		return;
38562306a36Sopenharmony_ci	}
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	/* process pattern */
38862306a36Sopenharmony_ci	pat = (struct pattern *)tone->pattern;
38962306a36Sopenharmony_ci	/* points to the current pattern */
39062306a36Sopenharmony_ci	index = tone->index; /* gives current sequence index */
39162306a36Sopenharmony_ci	count = tone->count; /* gives current sample */
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	/* copy sample */
39462306a36Sopenharmony_ci	while (len) {
39562306a36Sopenharmony_ci		/* find sample to start with */
39662306a36Sopenharmony_ci		while (42) {
39762306a36Sopenharmony_ci			/* wrap around */
39862306a36Sopenharmony_ci			if (!pat->seq[index]) {
39962306a36Sopenharmony_ci				count = 0;
40062306a36Sopenharmony_ci				index = 0;
40162306a36Sopenharmony_ci			}
40262306a36Sopenharmony_ci			/* check if we are currently playing this tone */
40362306a36Sopenharmony_ci			if (count < pat->seq[index])
40462306a36Sopenharmony_ci				break;
40562306a36Sopenharmony_ci			if (dsp_debug & DEBUG_DSP_TONE)
40662306a36Sopenharmony_ci				printk(KERN_DEBUG "%s: reaching next sequence "
40762306a36Sopenharmony_ci				       "(index=%d)\n", __func__, index);
40862306a36Sopenharmony_ci			count -= pat->seq[index];
40962306a36Sopenharmony_ci			index++;
41062306a36Sopenharmony_ci		}
41162306a36Sopenharmony_ci		/* calculate start and number of samples */
41262306a36Sopenharmony_ci		start = count % (*(pat->siz[index]));
41362306a36Sopenharmony_ci		num = len;
41462306a36Sopenharmony_ci		if (num + count > pat->seq[index])
41562306a36Sopenharmony_ci			num = pat->seq[index] - count;
41662306a36Sopenharmony_ci		if (num + start > (*(pat->siz[index])))
41762306a36Sopenharmony_ci			num = (*(pat->siz[index])) - start;
41862306a36Sopenharmony_ci		/* copy memory */
41962306a36Sopenharmony_ci		memcpy(data, pat->data[index] + start, num);
42062306a36Sopenharmony_ci		/* reduce length */
42162306a36Sopenharmony_ci		data += num;
42262306a36Sopenharmony_ci		count += num;
42362306a36Sopenharmony_ci		len -= num;
42462306a36Sopenharmony_ci	}
42562306a36Sopenharmony_ci	tone->index = index;
42662306a36Sopenharmony_ci	tone->count = count;
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	/* return sk_buff */
42962306a36Sopenharmony_ci	return;
43062306a36Sopenharmony_ci}
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci/*******************************
43462306a36Sopenharmony_ci * send HW message to hfc card *
43562306a36Sopenharmony_ci *******************************/
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_cistatic void
43862306a36Sopenharmony_cidsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
43962306a36Sopenharmony_ci{
44062306a36Sopenharmony_ci	struct sk_buff *nskb;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	/* unlocking is not required, because we don't expect a response */
44362306a36Sopenharmony_ci	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
44462306a36Sopenharmony_ci				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
44562306a36Sopenharmony_ci				GFP_ATOMIC);
44662306a36Sopenharmony_ci	if (nskb) {
44762306a36Sopenharmony_ci		if (dsp->ch.peer) {
44862306a36Sopenharmony_ci			if (dsp->ch.recv(dsp->ch.peer, nskb))
44962306a36Sopenharmony_ci				dev_kfree_skb(nskb);
45062306a36Sopenharmony_ci		} else
45162306a36Sopenharmony_ci			dev_kfree_skb(nskb);
45262306a36Sopenharmony_ci	}
45362306a36Sopenharmony_ci}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci/*****************
45762306a36Sopenharmony_ci * timer expires *
45862306a36Sopenharmony_ci *****************/
45962306a36Sopenharmony_civoid
46062306a36Sopenharmony_cidsp_tone_timeout(struct timer_list *t)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	struct dsp *dsp = from_timer(dsp, t, tone.tl);
46362306a36Sopenharmony_ci	struct dsp_tone *tone = &dsp->tone;
46462306a36Sopenharmony_ci	struct pattern *pat = (struct pattern *)tone->pattern;
46562306a36Sopenharmony_ci	int index = tone->index;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	if (!tone->tone)
46862306a36Sopenharmony_ci		return;
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	index++;
47162306a36Sopenharmony_ci	if (!pat->seq[index])
47262306a36Sopenharmony_ci		index = 0;
47362306a36Sopenharmony_ci	tone->index = index;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	/* set next tone */
47662306a36Sopenharmony_ci	if (pat->data[index] == DATA_S)
47762306a36Sopenharmony_ci		dsp_tone_hw_message(dsp, NULL, 0);
47862306a36Sopenharmony_ci	else
47962306a36Sopenharmony_ci		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
48062306a36Sopenharmony_ci	/* set timer */
48162306a36Sopenharmony_ci	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
48262306a36Sopenharmony_ci	add_timer(&tone->tl);
48362306a36Sopenharmony_ci}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/********************
48762306a36Sopenharmony_ci * set/release tone *
48862306a36Sopenharmony_ci ********************/
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci/*
49162306a36Sopenharmony_ci * tones are relaized by streaming or by special loop commands if supported
49262306a36Sopenharmony_ci * by hardware. when hardware is used, the patterns will be controlled by
49362306a36Sopenharmony_ci * timers.
49462306a36Sopenharmony_ci */
49562306a36Sopenharmony_ciint
49662306a36Sopenharmony_cidsp_tone(struct dsp *dsp, int tone)
49762306a36Sopenharmony_ci{
49862306a36Sopenharmony_ci	struct pattern *pat;
49962306a36Sopenharmony_ci	int i;
50062306a36Sopenharmony_ci	struct dsp_tone *tonet = &dsp->tone;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	tonet->software = 0;
50362306a36Sopenharmony_ci	tonet->hardware = 0;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	/* we turn off the tone */
50662306a36Sopenharmony_ci	if (!tone) {
50762306a36Sopenharmony_ci		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
50862306a36Sopenharmony_ci			del_timer(&tonet->tl);
50962306a36Sopenharmony_ci		if (dsp->features.hfc_loops)
51062306a36Sopenharmony_ci			dsp_tone_hw_message(dsp, NULL, 0);
51162306a36Sopenharmony_ci		tonet->tone = 0;
51262306a36Sopenharmony_ci		return 0;
51362306a36Sopenharmony_ci	}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	pat = NULL;
51662306a36Sopenharmony_ci	i = 0;
51762306a36Sopenharmony_ci	while (pattern[i].tone) {
51862306a36Sopenharmony_ci		if (pattern[i].tone == tone) {
51962306a36Sopenharmony_ci			pat = &pattern[i];
52062306a36Sopenharmony_ci			break;
52162306a36Sopenharmony_ci		}
52262306a36Sopenharmony_ci		i++;
52362306a36Sopenharmony_ci	}
52462306a36Sopenharmony_ci	if (!pat) {
52562306a36Sopenharmony_ci		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
52662306a36Sopenharmony_ci		return -EINVAL;
52762306a36Sopenharmony_ci	}
52862306a36Sopenharmony_ci	if (dsp_debug & DEBUG_DSP_TONE)
52962306a36Sopenharmony_ci		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
53062306a36Sopenharmony_ci		       __func__, tone, 0);
53162306a36Sopenharmony_ci	tonet->tone = tone;
53262306a36Sopenharmony_ci	tonet->pattern = pat;
53362306a36Sopenharmony_ci	tonet->index = 0;
53462306a36Sopenharmony_ci	tonet->count = 0;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	if (dsp->features.hfc_loops) {
53762306a36Sopenharmony_ci		tonet->hardware = 1;
53862306a36Sopenharmony_ci		/* set first tone */
53962306a36Sopenharmony_ci		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
54062306a36Sopenharmony_ci		/* set timer */
54162306a36Sopenharmony_ci		if (timer_pending(&tonet->tl))
54262306a36Sopenharmony_ci			del_timer(&tonet->tl);
54362306a36Sopenharmony_ci		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
54462306a36Sopenharmony_ci		add_timer(&tonet->tl);
54562306a36Sopenharmony_ci	} else {
54662306a36Sopenharmony_ci		tonet->software = 1;
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	return 0;
55062306a36Sopenharmony_ci}
551