18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Audio support data for ISDN4Linux. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright Andreas Eversberg (jolly@eversberg.eu) 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This software may be used and distributed according to the terms 78c2ecf20Sopenharmony_ci * of the GNU General Public License, incorporated herein by reference. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/gfp.h> 128c2ecf20Sopenharmony_ci#include <linux/mISDNif.h> 138c2ecf20Sopenharmony_ci#include <linux/mISDNdsp.h> 148c2ecf20Sopenharmony_ci#include "core.h" 158c2ecf20Sopenharmony_ci#include "dsp.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define DATA_S sample_silence 198c2ecf20Sopenharmony_ci#define SIZE_S (&sizeof_silence) 208c2ecf20Sopenharmony_ci#define DATA_GA sample_german_all 218c2ecf20Sopenharmony_ci#define SIZE_GA (&sizeof_german_all) 228c2ecf20Sopenharmony_ci#define DATA_GO sample_german_old 238c2ecf20Sopenharmony_ci#define SIZE_GO (&sizeof_german_old) 248c2ecf20Sopenharmony_ci#define DATA_DT sample_american_dialtone 258c2ecf20Sopenharmony_ci#define SIZE_DT (&sizeof_american_dialtone) 268c2ecf20Sopenharmony_ci#define DATA_RI sample_american_ringing 278c2ecf20Sopenharmony_ci#define SIZE_RI (&sizeof_american_ringing) 288c2ecf20Sopenharmony_ci#define DATA_BU sample_american_busy 298c2ecf20Sopenharmony_ci#define SIZE_BU (&sizeof_american_busy) 308c2ecf20Sopenharmony_ci#define DATA_S1 sample_special1 318c2ecf20Sopenharmony_ci#define SIZE_S1 (&sizeof_special1) 328c2ecf20Sopenharmony_ci#define DATA_S2 sample_special2 338c2ecf20Sopenharmony_ci#define SIZE_S2 (&sizeof_special2) 348c2ecf20Sopenharmony_ci#define DATA_S3 sample_special3 358c2ecf20Sopenharmony_ci#define SIZE_S3 (&sizeof_special3) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/***************/ 388c2ecf20Sopenharmony_ci/* tones loops */ 398c2ecf20Sopenharmony_ci/***************/ 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* all tones are alaw encoded */ 428c2ecf20Sopenharmony_ci/* the last sample+1 is in phase with the first sample. the error is low */ 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic u8 sample_german_all[] = { 458c2ecf20Sopenharmony_ci 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 468c2ecf20Sopenharmony_ci 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 478c2ecf20Sopenharmony_ci 0xdc, 0xfc, 0x6c, 488c2ecf20Sopenharmony_ci 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 498c2ecf20Sopenharmony_ci 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 508c2ecf20Sopenharmony_ci 0xdc, 0xfc, 0x6c, 518c2ecf20Sopenharmony_ci 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 528c2ecf20Sopenharmony_ci 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 538c2ecf20Sopenharmony_ci 0xdc, 0xfc, 0x6c, 548c2ecf20Sopenharmony_ci 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 558c2ecf20Sopenharmony_ci 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 568c2ecf20Sopenharmony_ci 0xdc, 0xfc, 0x6c, 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_cistatic u32 sizeof_german_all = sizeof(sample_german_all); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic u8 sample_german_old[] = { 618c2ecf20Sopenharmony_ci 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 628c2ecf20Sopenharmony_ci 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 638c2ecf20Sopenharmony_ci 0x8c, 648c2ecf20Sopenharmony_ci 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 658c2ecf20Sopenharmony_ci 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 668c2ecf20Sopenharmony_ci 0x8c, 678c2ecf20Sopenharmony_ci 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 688c2ecf20Sopenharmony_ci 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 698c2ecf20Sopenharmony_ci 0x8c, 708c2ecf20Sopenharmony_ci 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 718c2ecf20Sopenharmony_ci 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 728c2ecf20Sopenharmony_ci 0x8c, 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_cistatic u32 sizeof_german_old = sizeof(sample_german_old); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic u8 sample_american_dialtone[] = { 778c2ecf20Sopenharmony_ci 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c, 788c2ecf20Sopenharmony_ci 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d, 798c2ecf20Sopenharmony_ci 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0, 808c2ecf20Sopenharmony_ci 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67, 818c2ecf20Sopenharmony_ci 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67, 828c2ecf20Sopenharmony_ci 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef, 838c2ecf20Sopenharmony_ci 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8, 848c2ecf20Sopenharmony_ci 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61, 858c2ecf20Sopenharmony_ci 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e, 868c2ecf20Sopenharmony_ci 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30, 878c2ecf20Sopenharmony_ci 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d, 888c2ecf20Sopenharmony_ci 0x6d, 0x91, 0x19, 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_cistatic u32 sizeof_american_dialtone = sizeof(sample_american_dialtone); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic u8 sample_american_ringing[] = { 938c2ecf20Sopenharmony_ci 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90, 948c2ecf20Sopenharmony_ci 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed, 958c2ecf20Sopenharmony_ci 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c, 968c2ecf20Sopenharmony_ci 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d, 978c2ecf20Sopenharmony_ci 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec, 988c2ecf20Sopenharmony_ci 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11, 998c2ecf20Sopenharmony_ci 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00, 1008c2ecf20Sopenharmony_ci 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39, 1018c2ecf20Sopenharmony_ci 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6, 1028c2ecf20Sopenharmony_ci 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3, 1038c2ecf20Sopenharmony_ci 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b, 1048c2ecf20Sopenharmony_ci 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f, 1058c2ecf20Sopenharmony_ci 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56, 1068c2ecf20Sopenharmony_ci 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59, 1078c2ecf20Sopenharmony_ci 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30, 1088c2ecf20Sopenharmony_ci 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d, 1098c2ecf20Sopenharmony_ci 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c, 1108c2ecf20Sopenharmony_ci 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd, 1118c2ecf20Sopenharmony_ci 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc, 1128c2ecf20Sopenharmony_ci 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d, 1138c2ecf20Sopenharmony_ci 0x4d, 0xbd, 0x0d, 0xad, 0xe1, 1148c2ecf20Sopenharmony_ci}; 1158c2ecf20Sopenharmony_cistatic u32 sizeof_american_ringing = sizeof(sample_american_ringing); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic u8 sample_american_busy[] = { 1188c2ecf20Sopenharmony_ci 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66, 1198c2ecf20Sopenharmony_ci 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96, 1208c2ecf20Sopenharmony_ci 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57, 1218c2ecf20Sopenharmony_ci 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f, 1228c2ecf20Sopenharmony_ci 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40, 1238c2ecf20Sopenharmony_ci 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d, 1248c2ecf20Sopenharmony_ci 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c, 1258c2ecf20Sopenharmony_ci 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d, 1268c2ecf20Sopenharmony_ci 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40, 1278c2ecf20Sopenharmony_ci 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7, 1288c2ecf20Sopenharmony_ci 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a, 1298c2ecf20Sopenharmony_ci 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7, 1308c2ecf20Sopenharmony_ci 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40, 1318c2ecf20Sopenharmony_ci 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d, 1328c2ecf20Sopenharmony_ci 0x4d, 0x4d, 0x6d, 0x01, 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_cistatic u32 sizeof_american_busy = sizeof(sample_american_busy); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic u8 sample_special1[] = { 1378c2ecf20Sopenharmony_ci 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d, 1388c2ecf20Sopenharmony_ci 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd, 1398c2ecf20Sopenharmony_ci 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd, 1408c2ecf20Sopenharmony_ci 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd, 1418c2ecf20Sopenharmony_ci 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed, 1428c2ecf20Sopenharmony_ci 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41, 1438c2ecf20Sopenharmony_ci 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7, 1448c2ecf20Sopenharmony_ci 0x6d, 0xbd, 0x2d, 1458c2ecf20Sopenharmony_ci}; 1468c2ecf20Sopenharmony_cistatic u32 sizeof_special1 = sizeof(sample_special1); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic u8 sample_special2[] = { 1498c2ecf20Sopenharmony_ci 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, 1508c2ecf20Sopenharmony_ci 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, 1518c2ecf20Sopenharmony_ci 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, 1528c2ecf20Sopenharmony_ci 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, 1538c2ecf20Sopenharmony_ci 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, 1548c2ecf20Sopenharmony_ci 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, 1558c2ecf20Sopenharmony_ci 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, 1568c2ecf20Sopenharmony_ci 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, 1578c2ecf20Sopenharmony_ci 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, 1588c2ecf20Sopenharmony_ci 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_cistatic u32 sizeof_special2 = sizeof(sample_special2); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic u8 sample_special3[] = { 1638c2ecf20Sopenharmony_ci 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, 1648c2ecf20Sopenharmony_ci 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, 1658c2ecf20Sopenharmony_ci 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, 1668c2ecf20Sopenharmony_ci 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, 1678c2ecf20Sopenharmony_ci 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, 1688c2ecf20Sopenharmony_ci 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, 1698c2ecf20Sopenharmony_ci 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, 1708c2ecf20Sopenharmony_ci 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, 1718c2ecf20Sopenharmony_ci 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, 1728c2ecf20Sopenharmony_ci 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_cistatic u32 sizeof_special3 = sizeof(sample_special3); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic u8 sample_silence[] = { 1778c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1788c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1798c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1808c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1818c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1828c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1838c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1848c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1858c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1868c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1878c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1888c2ecf20Sopenharmony_ci 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_cistatic u32 sizeof_silence = sizeof(sample_silence); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistruct tones_samples { 1938c2ecf20Sopenharmony_ci u32 *len; 1948c2ecf20Sopenharmony_ci u8 *data; 1958c2ecf20Sopenharmony_ci}; 1968c2ecf20Sopenharmony_cistatic struct 1978c2ecf20Sopenharmony_citones_samples samples[] = { 1988c2ecf20Sopenharmony_ci {&sizeof_german_all, sample_german_all}, 1998c2ecf20Sopenharmony_ci {&sizeof_german_old, sample_german_old}, 2008c2ecf20Sopenharmony_ci {&sizeof_american_dialtone, sample_american_dialtone}, 2018c2ecf20Sopenharmony_ci {&sizeof_american_ringing, sample_american_ringing}, 2028c2ecf20Sopenharmony_ci {&sizeof_american_busy, sample_american_busy}, 2038c2ecf20Sopenharmony_ci {&sizeof_special1, sample_special1}, 2048c2ecf20Sopenharmony_ci {&sizeof_special2, sample_special2}, 2058c2ecf20Sopenharmony_ci {&sizeof_special3, sample_special3}, 2068c2ecf20Sopenharmony_ci {NULL, NULL}, 2078c2ecf20Sopenharmony_ci}; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/*********************************** 2108c2ecf20Sopenharmony_ci * generate ulaw from alaw samples * 2118c2ecf20Sopenharmony_ci ***********************************/ 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_civoid 2148c2ecf20Sopenharmony_cidsp_audio_generate_ulaw_samples(void) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci int i, j; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci i = 0; 2198c2ecf20Sopenharmony_ci while (samples[i].len) { 2208c2ecf20Sopenharmony_ci j = 0; 2218c2ecf20Sopenharmony_ci while (j < (*samples[i].len)) { 2228c2ecf20Sopenharmony_ci samples[i].data[j] = 2238c2ecf20Sopenharmony_ci dsp_audio_alaw_to_ulaw[samples[i].data[j]]; 2248c2ecf20Sopenharmony_ci j++; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci i++; 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci/**************************** 2328c2ecf20Sopenharmony_ci * tone sequence definition * 2338c2ecf20Sopenharmony_ci ****************************/ 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic struct pattern { 2368c2ecf20Sopenharmony_ci int tone; 2378c2ecf20Sopenharmony_ci u8 *data[10]; 2388c2ecf20Sopenharmony_ci u32 *siz[10]; 2398c2ecf20Sopenharmony_ci u32 seq[10]; 2408c2ecf20Sopenharmony_ci} pattern[] = { 2418c2ecf20Sopenharmony_ci {TONE_GERMAN_DIALTONE, 2428c2ecf20Sopenharmony_ci {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2438c2ecf20Sopenharmony_ci {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2448c2ecf20Sopenharmony_ci {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDDIALTONE, 2478c2ecf20Sopenharmony_ci {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2488c2ecf20Sopenharmony_ci {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2498c2ecf20Sopenharmony_ci {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci {TONE_AMERICAN_DIALTONE, 2528c2ecf20Sopenharmony_ci {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2538c2ecf20Sopenharmony_ci {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2548c2ecf20Sopenharmony_ci {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci {TONE_GERMAN_DIALPBX, 2578c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, 2588c2ecf20Sopenharmony_ci NULL}, 2598c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, 2608c2ecf20Sopenharmony_ci NULL}, 2618c2ecf20Sopenharmony_ci {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDDIALPBX, 2648c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, 2658c2ecf20Sopenharmony_ci NULL}, 2668c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, 2678c2ecf20Sopenharmony_ci NULL}, 2688c2ecf20Sopenharmony_ci {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci {TONE_AMERICAN_DIALPBX, 2718c2ecf20Sopenharmony_ci {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, 2728c2ecf20Sopenharmony_ci NULL}, 2738c2ecf20Sopenharmony_ci {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, 2748c2ecf20Sopenharmony_ci NULL}, 2758c2ecf20Sopenharmony_ci {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci {TONE_GERMAN_RINGING, 2788c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2798c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2808c2ecf20Sopenharmony_ci {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDRINGING, 2838c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2848c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2858c2ecf20Sopenharmony_ci {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} }, 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci {TONE_AMERICAN_RINGING, 2888c2ecf20Sopenharmony_ci {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2898c2ecf20Sopenharmony_ci {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 2908c2ecf20Sopenharmony_ci {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci {TONE_GERMAN_RINGPBX, 2938c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 2948c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 2958c2ecf20Sopenharmony_ci {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDRINGPBX, 2988c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 2998c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3008c2ecf20Sopenharmony_ci {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci {TONE_AMERICAN_RINGPBX, 3038c2ecf20Sopenharmony_ci {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3048c2ecf20Sopenharmony_ci {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3058c2ecf20Sopenharmony_ci {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci {TONE_GERMAN_BUSY, 3088c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3098c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3108c2ecf20Sopenharmony_ci {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDBUSY, 3138c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3148c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3158c2ecf20Sopenharmony_ci {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci {TONE_AMERICAN_BUSY, 3188c2ecf20Sopenharmony_ci {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3198c2ecf20Sopenharmony_ci {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3208c2ecf20Sopenharmony_ci {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci {TONE_GERMAN_HANGUP, 3238c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3248c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3258c2ecf20Sopenharmony_ci {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci {TONE_GERMAN_OLDHANGUP, 3288c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3298c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3308c2ecf20Sopenharmony_ci {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci {TONE_AMERICAN_HANGUP, 3338c2ecf20Sopenharmony_ci {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3348c2ecf20Sopenharmony_ci {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3358c2ecf20Sopenharmony_ci {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci {TONE_SPECIAL_INFO, 3388c2ecf20Sopenharmony_ci {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3398c2ecf20Sopenharmony_ci {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3408c2ecf20Sopenharmony_ci {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} }, 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci {TONE_GERMAN_GASSENBESETZT, 3438c2ecf20Sopenharmony_ci {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3448c2ecf20Sopenharmony_ci {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3458c2ecf20Sopenharmony_ci {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} }, 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci {TONE_GERMAN_AUFSCHALTTON, 3488c2ecf20Sopenharmony_ci {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3498c2ecf20Sopenharmony_ci {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 3508c2ecf20Sopenharmony_ci {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} }, 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci {0, 3538c2ecf20Sopenharmony_ci {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3548c2ecf20Sopenharmony_ci {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 3558c2ecf20Sopenharmony_ci {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 3568c2ecf20Sopenharmony_ci}; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci/****************** 3598c2ecf20Sopenharmony_ci * copy tone data * 3608c2ecf20Sopenharmony_ci ******************/ 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci/* an sk_buff is generated from the number of samples needed. 3638c2ecf20Sopenharmony_ci * the count will be changed and may begin from 0 each pattern period. 3648c2ecf20Sopenharmony_ci * the clue is to precalculate the pointers and legths to use only one 3658c2ecf20Sopenharmony_ci * memcpy per function call, or two memcpy if the tone sequence changes. 3668c2ecf20Sopenharmony_ci * 3678c2ecf20Sopenharmony_ci * pattern - the type of the pattern 3688c2ecf20Sopenharmony_ci * count - the sample from the beginning of the pattern (phase) 3698c2ecf20Sopenharmony_ci * len - the number of bytes 3708c2ecf20Sopenharmony_ci * 3718c2ecf20Sopenharmony_ci * return - the sk_buff with the sample 3728c2ecf20Sopenharmony_ci * 3738c2ecf20Sopenharmony_ci * if tones has finished (e.g. knocking tone), dsp->tones is turned off 3748c2ecf20Sopenharmony_ci */ 3758c2ecf20Sopenharmony_civoid dsp_tone_copy(struct dsp *dsp, u8 *data, int len) 3768c2ecf20Sopenharmony_ci{ 3778c2ecf20Sopenharmony_ci int index, count, start, num; 3788c2ecf20Sopenharmony_ci struct pattern *pat; 3798c2ecf20Sopenharmony_ci struct dsp_tone *tone = &dsp->tone; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci /* if we have no tone, we copy silence */ 3828c2ecf20Sopenharmony_ci if (!tone->tone) { 3838c2ecf20Sopenharmony_ci memset(data, dsp_silence, len); 3848c2ecf20Sopenharmony_ci return; 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci /* process pattern */ 3888c2ecf20Sopenharmony_ci pat = (struct pattern *)tone->pattern; 3898c2ecf20Sopenharmony_ci /* points to the current pattern */ 3908c2ecf20Sopenharmony_ci index = tone->index; /* gives current sequence index */ 3918c2ecf20Sopenharmony_ci count = tone->count; /* gives current sample */ 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* copy sample */ 3948c2ecf20Sopenharmony_ci while (len) { 3958c2ecf20Sopenharmony_ci /* find sample to start with */ 3968c2ecf20Sopenharmony_ci while (42) { 3978c2ecf20Sopenharmony_ci /* wrap around */ 3988c2ecf20Sopenharmony_ci if (!pat->seq[index]) { 3998c2ecf20Sopenharmony_ci count = 0; 4008c2ecf20Sopenharmony_ci index = 0; 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci /* check if we are currently playing this tone */ 4038c2ecf20Sopenharmony_ci if (count < pat->seq[index]) 4048c2ecf20Sopenharmony_ci break; 4058c2ecf20Sopenharmony_ci if (dsp_debug & DEBUG_DSP_TONE) 4068c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s: reaching next sequence " 4078c2ecf20Sopenharmony_ci "(index=%d)\n", __func__, index); 4088c2ecf20Sopenharmony_ci count -= pat->seq[index]; 4098c2ecf20Sopenharmony_ci index++; 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci /* calculate start and number of samples */ 4128c2ecf20Sopenharmony_ci start = count % (*(pat->siz[index])); 4138c2ecf20Sopenharmony_ci num = len; 4148c2ecf20Sopenharmony_ci if (num + count > pat->seq[index]) 4158c2ecf20Sopenharmony_ci num = pat->seq[index] - count; 4168c2ecf20Sopenharmony_ci if (num + start > (*(pat->siz[index]))) 4178c2ecf20Sopenharmony_ci num = (*(pat->siz[index])) - start; 4188c2ecf20Sopenharmony_ci /* copy memory */ 4198c2ecf20Sopenharmony_ci memcpy(data, pat->data[index] + start, num); 4208c2ecf20Sopenharmony_ci /* reduce length */ 4218c2ecf20Sopenharmony_ci data += num; 4228c2ecf20Sopenharmony_ci count += num; 4238c2ecf20Sopenharmony_ci len -= num; 4248c2ecf20Sopenharmony_ci } 4258c2ecf20Sopenharmony_ci tone->index = index; 4268c2ecf20Sopenharmony_ci tone->count = count; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci /* return sk_buff */ 4298c2ecf20Sopenharmony_ci return; 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci/******************************* 4348c2ecf20Sopenharmony_ci * send HW message to hfc card * 4358c2ecf20Sopenharmony_ci *******************************/ 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_cistatic void 4388c2ecf20Sopenharmony_cidsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len) 4398c2ecf20Sopenharmony_ci{ 4408c2ecf20Sopenharmony_ci struct sk_buff *nskb; 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci /* unlocking is not required, because we don't expect a response */ 4438c2ecf20Sopenharmony_ci nskb = _alloc_mISDN_skb(PH_CONTROL_REQ, 4448c2ecf20Sopenharmony_ci (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample, 4458c2ecf20Sopenharmony_ci GFP_ATOMIC); 4468c2ecf20Sopenharmony_ci if (nskb) { 4478c2ecf20Sopenharmony_ci if (dsp->ch.peer) { 4488c2ecf20Sopenharmony_ci if (dsp->ch.recv(dsp->ch.peer, nskb)) 4498c2ecf20Sopenharmony_ci dev_kfree_skb(nskb); 4508c2ecf20Sopenharmony_ci } else 4518c2ecf20Sopenharmony_ci dev_kfree_skb(nskb); 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci} 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci/***************** 4578c2ecf20Sopenharmony_ci * timer expires * 4588c2ecf20Sopenharmony_ci *****************/ 4598c2ecf20Sopenharmony_civoid 4608c2ecf20Sopenharmony_cidsp_tone_timeout(struct timer_list *t) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci struct dsp *dsp = from_timer(dsp, t, tone.tl); 4638c2ecf20Sopenharmony_ci struct dsp_tone *tone = &dsp->tone; 4648c2ecf20Sopenharmony_ci struct pattern *pat = (struct pattern *)tone->pattern; 4658c2ecf20Sopenharmony_ci int index = tone->index; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci if (!tone->tone) 4688c2ecf20Sopenharmony_ci return; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci index++; 4718c2ecf20Sopenharmony_ci if (!pat->seq[index]) 4728c2ecf20Sopenharmony_ci index = 0; 4738c2ecf20Sopenharmony_ci tone->index = index; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci /* set next tone */ 4768c2ecf20Sopenharmony_ci if (pat->data[index] == DATA_S) 4778c2ecf20Sopenharmony_ci dsp_tone_hw_message(dsp, NULL, 0); 4788c2ecf20Sopenharmony_ci else 4798c2ecf20Sopenharmony_ci dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index])); 4808c2ecf20Sopenharmony_ci /* set timer */ 4818c2ecf20Sopenharmony_ci tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000; 4828c2ecf20Sopenharmony_ci add_timer(&tone->tl); 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci/******************** 4878c2ecf20Sopenharmony_ci * set/release tone * 4888c2ecf20Sopenharmony_ci ********************/ 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci/* 4918c2ecf20Sopenharmony_ci * tones are relaized by streaming or by special loop commands if supported 4928c2ecf20Sopenharmony_ci * by hardware. when hardware is used, the patterns will be controlled by 4938c2ecf20Sopenharmony_ci * timers. 4948c2ecf20Sopenharmony_ci */ 4958c2ecf20Sopenharmony_ciint 4968c2ecf20Sopenharmony_cidsp_tone(struct dsp *dsp, int tone) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci struct pattern *pat; 4998c2ecf20Sopenharmony_ci int i; 5008c2ecf20Sopenharmony_ci struct dsp_tone *tonet = &dsp->tone; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci tonet->software = 0; 5038c2ecf20Sopenharmony_ci tonet->hardware = 0; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci /* we turn off the tone */ 5068c2ecf20Sopenharmony_ci if (!tone) { 5078c2ecf20Sopenharmony_ci if (dsp->features.hfc_loops && timer_pending(&tonet->tl)) 5088c2ecf20Sopenharmony_ci del_timer(&tonet->tl); 5098c2ecf20Sopenharmony_ci if (dsp->features.hfc_loops) 5108c2ecf20Sopenharmony_ci dsp_tone_hw_message(dsp, NULL, 0); 5118c2ecf20Sopenharmony_ci tonet->tone = 0; 5128c2ecf20Sopenharmony_ci return 0; 5138c2ecf20Sopenharmony_ci } 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci pat = NULL; 5168c2ecf20Sopenharmony_ci i = 0; 5178c2ecf20Sopenharmony_ci while (pattern[i].tone) { 5188c2ecf20Sopenharmony_ci if (pattern[i].tone == tone) { 5198c2ecf20Sopenharmony_ci pat = &pattern[i]; 5208c2ecf20Sopenharmony_ci break; 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci i++; 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci if (!pat) { 5258c2ecf20Sopenharmony_ci printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone); 5268c2ecf20Sopenharmony_ci return -EINVAL; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci if (dsp_debug & DEBUG_DSP_TONE) 5298c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n", 5308c2ecf20Sopenharmony_ci __func__, tone, 0); 5318c2ecf20Sopenharmony_ci tonet->tone = tone; 5328c2ecf20Sopenharmony_ci tonet->pattern = pat; 5338c2ecf20Sopenharmony_ci tonet->index = 0; 5348c2ecf20Sopenharmony_ci tonet->count = 0; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci if (dsp->features.hfc_loops) { 5378c2ecf20Sopenharmony_ci tonet->hardware = 1; 5388c2ecf20Sopenharmony_ci /* set first tone */ 5398c2ecf20Sopenharmony_ci dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0])); 5408c2ecf20Sopenharmony_ci /* set timer */ 5418c2ecf20Sopenharmony_ci if (timer_pending(&tonet->tl)) 5428c2ecf20Sopenharmony_ci del_timer(&tonet->tl); 5438c2ecf20Sopenharmony_ci tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000; 5448c2ecf20Sopenharmony_ci add_timer(&tonet->tl); 5458c2ecf20Sopenharmony_ci } else { 5468c2ecf20Sopenharmony_ci tonet->software = 1; 5478c2ecf20Sopenharmony_ci } 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci return 0; 5508c2ecf20Sopenharmony_ci} 551