cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsp_tones.c (17359B)


      1/*
      2 * Audio support data for ISDN4Linux.
      3 *
      4 * Copyright Andreas Eversberg (jolly@eversberg.eu)
      5 *
      6 * This software may be used and distributed according to the terms
      7 * of the GNU General Public License, incorporated herein by reference.
      8 *
      9 */
     10
     11#include <linux/gfp.h>
     12#include <linux/mISDNif.h>
     13#include <linux/mISDNdsp.h>
     14#include "core.h"
     15#include "dsp.h"
     16
     17
     18#define DATA_S sample_silence
     19#define SIZE_S (&sizeof_silence)
     20#define DATA_GA sample_german_all
     21#define SIZE_GA (&sizeof_german_all)
     22#define DATA_GO sample_german_old
     23#define SIZE_GO (&sizeof_german_old)
     24#define DATA_DT sample_american_dialtone
     25#define SIZE_DT (&sizeof_american_dialtone)
     26#define DATA_RI sample_american_ringing
     27#define SIZE_RI (&sizeof_american_ringing)
     28#define DATA_BU sample_american_busy
     29#define SIZE_BU (&sizeof_american_busy)
     30#define DATA_S1 sample_special1
     31#define SIZE_S1 (&sizeof_special1)
     32#define DATA_S2 sample_special2
     33#define SIZE_S2 (&sizeof_special2)
     34#define DATA_S3 sample_special3
     35#define SIZE_S3 (&sizeof_special3)
     36
     37/***************/
     38/* tones loops */
     39/***************/
     40
     41/* all tones are alaw encoded */
     42/* the last sample+1 is in phase with the first sample. the error is low */
     43
     44static u8 sample_german_all[] = {
     45	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
     46	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
     47	0xdc, 0xfc, 0x6c,
     48	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
     49	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
     50	0xdc, 0xfc, 0x6c,
     51	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
     52	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
     53	0xdc, 0xfc, 0x6c,
     54	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
     55	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
     56	0xdc, 0xfc, 0x6c,
     57};
     58static u32 sizeof_german_all = sizeof(sample_german_all);
     59
     60static u8 sample_german_old[] = {
     61	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
     62	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
     63	0x8c,
     64	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
     65	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
     66	0x8c,
     67	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
     68	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
     69	0x8c,
     70	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
     71	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
     72	0x8c,
     73};
     74static u32 sizeof_german_old = sizeof(sample_german_old);
     75
     76static u8 sample_american_dialtone[] = {
     77	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
     78	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
     79	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
     80	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
     81	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
     82	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
     83	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
     84	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
     85	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
     86	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
     87	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
     88	0x6d, 0x91, 0x19,
     89};
     90static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
     91
     92static u8 sample_american_ringing[] = {
     93	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
     94	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
     95	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
     96	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
     97	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
     98	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
     99	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
    100	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
    101	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
    102	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
    103	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
    104	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
    105	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
    106	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
    107	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
    108	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
    109	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
    110	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
    111	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
    112	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
    113	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
    114};
    115static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
    116
    117static u8 sample_american_busy[] = {
    118	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
    119	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
    120	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
    121	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
    122	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
    123	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
    124	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
    125	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
    126	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
    127	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
    128	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
    129	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
    130	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
    131	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
    132	0x4d, 0x4d, 0x6d, 0x01,
    133};
    134static u32 sizeof_american_busy = sizeof(sample_american_busy);
    135
    136static u8 sample_special1[] = {
    137	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
    138	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
    139	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
    140	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
    141	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
    142	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
    143	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
    144	0x6d, 0xbd, 0x2d,
    145};
    146static u32 sizeof_special1 = sizeof(sample_special1);
    147
    148static u8 sample_special2[] = {
    149	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
    150	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
    151	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
    152	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
    153	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
    154	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
    155	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
    156	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
    157	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
    158	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
    159};
    160static u32 sizeof_special2 = sizeof(sample_special2);
    161
    162static u8 sample_special3[] = {
    163	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
    164	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
    165	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
    166	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
    167	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
    168	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
    169	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
    170	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
    171	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
    172	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
    173};
    174static u32 sizeof_special3 = sizeof(sample_special3);
    175
    176static u8 sample_silence[] = {
    177	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    178	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    179	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    180	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    181	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    182	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    183	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    184	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    185	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    186	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    187	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    188	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
    189};
    190static u32 sizeof_silence = sizeof(sample_silence);
    191
    192struct tones_samples {
    193	u32 *len;
    194	u8 *data;
    195};
    196static struct
    197tones_samples samples[] = {
    198	{&sizeof_german_all, sample_german_all},
    199	{&sizeof_german_old, sample_german_old},
    200	{&sizeof_american_dialtone, sample_american_dialtone},
    201	{&sizeof_american_ringing, sample_american_ringing},
    202	{&sizeof_american_busy, sample_american_busy},
    203	{&sizeof_special1, sample_special1},
    204	{&sizeof_special2, sample_special2},
    205	{&sizeof_special3, sample_special3},
    206	{NULL, NULL},
    207};
    208
    209/***********************************
    210 * generate ulaw from alaw samples *
    211 ***********************************/
    212
    213void
    214dsp_audio_generate_ulaw_samples(void)
    215{
    216	int i, j;
    217
    218	i = 0;
    219	while (samples[i].len) {
    220		j = 0;
    221		while (j < (*samples[i].len)) {
    222			samples[i].data[j] =
    223				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
    224			j++;
    225		}
    226		i++;
    227	}
    228}
    229
    230
    231/****************************
    232 * tone sequence definition *
    233 ****************************/
    234
    235static struct pattern {
    236	int tone;
    237	u8 *data[10];
    238	u32 *siz[10];
    239	u32 seq[10];
    240} pattern[] = {
    241	{TONE_GERMAN_DIALTONE,
    242	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    243	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    244	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
    245
    246	{TONE_GERMAN_OLDDIALTONE,
    247	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    248	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    249	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
    250
    251	{TONE_AMERICAN_DIALTONE,
    252	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    253	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    254	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
    255
    256	{TONE_GERMAN_DIALPBX,
    257	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
    258	  NULL},
    259	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
    260	  NULL},
    261	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
    262
    263	{TONE_GERMAN_OLDDIALPBX,
    264	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
    265	  NULL},
    266	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
    267	  NULL},
    268	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
    269
    270	{TONE_AMERICAN_DIALPBX,
    271	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
    272	  NULL},
    273	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
    274	  NULL},
    275	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
    276
    277	{TONE_GERMAN_RINGING,
    278	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    279	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    280	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
    281
    282	{TONE_GERMAN_OLDRINGING,
    283	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    284	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    285	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
    286
    287	{TONE_AMERICAN_RINGING,
    288	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    289	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    290	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
    291
    292	{TONE_GERMAN_RINGPBX,
    293	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
    294	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
    295	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
    296
    297	{TONE_GERMAN_OLDRINGPBX,
    298	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
    299	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
    300	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
    301
    302	{TONE_AMERICAN_RINGPBX,
    303	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
    304	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
    305	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
    306
    307	{TONE_GERMAN_BUSY,
    308	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    309	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    310	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
    311
    312	{TONE_GERMAN_OLDBUSY,
    313	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    314	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    315	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
    316
    317	{TONE_AMERICAN_BUSY,
    318	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    319	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    320	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
    321
    322	{TONE_GERMAN_HANGUP,
    323	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    324	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    325	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
    326
    327	{TONE_GERMAN_OLDHANGUP,
    328	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    329	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    330	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
    331
    332	{TONE_AMERICAN_HANGUP,
    333	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    334	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    335	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
    336
    337	{TONE_SPECIAL_INFO,
    338	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
    339	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
    340	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
    341
    342	{TONE_GERMAN_GASSENBESETZT,
    343	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    344	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    345	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
    346
    347	{TONE_GERMAN_AUFSCHALTTON,
    348	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
    349	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
    350	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
    351
    352	{0,
    353	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    354	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    355	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
    356};
    357
    358/******************
    359 * copy tone data *
    360 ******************/
    361
    362/* an sk_buff is generated from the number of samples needed.
    363 * the count will be changed and may begin from 0 each pattern period.
    364 * the clue is to precalculate the pointers and legths to use only one
    365 * memcpy per function call, or two memcpy if the tone sequence changes.
    366 *
    367 * pattern - the type of the pattern
    368 * count - the sample from the beginning of the pattern (phase)
    369 * len - the number of bytes
    370 *
    371 * return - the sk_buff with the sample
    372 *
    373 * if tones has finished (e.g. knocking tone), dsp->tones is turned off
    374 */
    375void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
    376{
    377	int index, count, start, num;
    378	struct pattern *pat;
    379	struct dsp_tone *tone = &dsp->tone;
    380
    381	/* if we have no tone, we copy silence */
    382	if (!tone->tone) {
    383		memset(data, dsp_silence, len);
    384		return;
    385	}
    386
    387	/* process pattern */
    388	pat = (struct pattern *)tone->pattern;
    389	/* points to the current pattern */
    390	index = tone->index; /* gives current sequence index */
    391	count = tone->count; /* gives current sample */
    392
    393	/* copy sample */
    394	while (len) {
    395		/* find sample to start with */
    396		while (42) {
    397			/* wrap around */
    398			if (!pat->seq[index]) {
    399				count = 0;
    400				index = 0;
    401			}
    402			/* check if we are currently playing this tone */
    403			if (count < pat->seq[index])
    404				break;
    405			if (dsp_debug & DEBUG_DSP_TONE)
    406				printk(KERN_DEBUG "%s: reaching next sequence "
    407				       "(index=%d)\n", __func__, index);
    408			count -= pat->seq[index];
    409			index++;
    410		}
    411		/* calculate start and number of samples */
    412		start = count % (*(pat->siz[index]));
    413		num = len;
    414		if (num + count > pat->seq[index])
    415			num = pat->seq[index] - count;
    416		if (num + start > (*(pat->siz[index])))
    417			num = (*(pat->siz[index])) - start;
    418		/* copy memory */
    419		memcpy(data, pat->data[index] + start, num);
    420		/* reduce length */
    421		data += num;
    422		count += num;
    423		len -= num;
    424	}
    425	tone->index = index;
    426	tone->count = count;
    427
    428	/* return sk_buff */
    429	return;
    430}
    431
    432
    433/*******************************
    434 * send HW message to hfc card *
    435 *******************************/
    436
    437static void
    438dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
    439{
    440	struct sk_buff *nskb;
    441
    442	/* unlocking is not required, because we don't expect a response */
    443	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
    444				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
    445				GFP_ATOMIC);
    446	if (nskb) {
    447		if (dsp->ch.peer) {
    448			if (dsp->ch.recv(dsp->ch.peer, nskb))
    449				dev_kfree_skb(nskb);
    450		} else
    451			dev_kfree_skb(nskb);
    452	}
    453}
    454
    455
    456/*****************
    457 * timer expires *
    458 *****************/
    459void
    460dsp_tone_timeout(struct timer_list *t)
    461{
    462	struct dsp *dsp = from_timer(dsp, t, tone.tl);
    463	struct dsp_tone *tone = &dsp->tone;
    464	struct pattern *pat = (struct pattern *)tone->pattern;
    465	int index = tone->index;
    466
    467	if (!tone->tone)
    468		return;
    469
    470	index++;
    471	if (!pat->seq[index])
    472		index = 0;
    473	tone->index = index;
    474
    475	/* set next tone */
    476	if (pat->data[index] == DATA_S)
    477		dsp_tone_hw_message(dsp, NULL, 0);
    478	else
    479		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
    480	/* set timer */
    481	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
    482	add_timer(&tone->tl);
    483}
    484
    485
    486/********************
    487 * set/release tone *
    488 ********************/
    489
    490/*
    491 * tones are relaized by streaming or by special loop commands if supported
    492 * by hardware. when hardware is used, the patterns will be controlled by
    493 * timers.
    494 */
    495int
    496dsp_tone(struct dsp *dsp, int tone)
    497{
    498	struct pattern *pat;
    499	int i;
    500	struct dsp_tone *tonet = &dsp->tone;
    501
    502	tonet->software = 0;
    503	tonet->hardware = 0;
    504
    505	/* we turn off the tone */
    506	if (!tone) {
    507		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
    508			del_timer(&tonet->tl);
    509		if (dsp->features.hfc_loops)
    510			dsp_tone_hw_message(dsp, NULL, 0);
    511		tonet->tone = 0;
    512		return 0;
    513	}
    514
    515	pat = NULL;
    516	i = 0;
    517	while (pattern[i].tone) {
    518		if (pattern[i].tone == tone) {
    519			pat = &pattern[i];
    520			break;
    521		}
    522		i++;
    523	}
    524	if (!pat) {
    525		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
    526		return -EINVAL;
    527	}
    528	if (dsp_debug & DEBUG_DSP_TONE)
    529		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
    530		       __func__, tone, 0);
    531	tonet->tone = tone;
    532	tonet->pattern = pat;
    533	tonet->index = 0;
    534	tonet->count = 0;
    535
    536	if (dsp->features.hfc_loops) {
    537		tonet->hardware = 1;
    538		/* set first tone */
    539		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
    540		/* set timer */
    541		if (timer_pending(&tonet->tl))
    542			del_timer(&tonet->tl);
    543		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
    544		add_timer(&tonet->tl);
    545	} else {
    546		tonet->software = 1;
    547	}
    548
    549	return 0;
    550}