xref: /openbmc/linux/drivers/isdn/mISDN/l1oip_codec.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*de6cc651SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
23712b42dSKarsten Keil /*
33712b42dSKarsten Keil 
43712b42dSKarsten Keil  * l1oip_codec.c  generic codec using lookup table
53712b42dSKarsten Keil  *  -> conversion from a-Law to u-Law
63712b42dSKarsten Keil  *  -> conversion from u-Law to a-Law
73712b42dSKarsten Keil  *  -> compression by reducing the number of sample resolution to 4
83712b42dSKarsten Keil  *
93712b42dSKarsten Keil  * NOTE: It is not compatible with any standard codec like ADPCM.
103712b42dSKarsten Keil  *
113712b42dSKarsten Keil  * Author	Andreas Eversberg (jolly@eversberg.eu)
123712b42dSKarsten Keil  *
133712b42dSKarsten Keil 
143712b42dSKarsten Keil  */
153712b42dSKarsten Keil 
163712b42dSKarsten Keil /*
173712b42dSKarsten Keil 
183712b42dSKarsten Keil   How the codec works:
193712b42dSKarsten Keil   --------------------
203712b42dSKarsten Keil 
213712b42dSKarsten Keil   The volume is increased to increase the dynamic range of the audio signal.
223712b42dSKarsten Keil   Each sample is converted to a-LAW with only 16 steps of level resolution.
233712b42dSKarsten Keil   A pair of two samples are stored in one byte.
243712b42dSKarsten Keil 
253712b42dSKarsten Keil   The first byte is stored in the upper bits, the second byte is stored in the
263712b42dSKarsten Keil   lower bits.
273712b42dSKarsten Keil 
283712b42dSKarsten Keil   To speed up compression and decompression, two lookup tables are formed:
293712b42dSKarsten Keil 
303712b42dSKarsten Keil   - 16 bits index for two samples (law encoded) with 8 bit compressed result.
313712b42dSKarsten Keil   - 8 bits index for one compressed data with 16 bits decompressed result.
323712b42dSKarsten Keil 
333712b42dSKarsten Keil   NOTE: The bytes are handled as they are law-encoded.
343712b42dSKarsten Keil 
353712b42dSKarsten Keil */
363712b42dSKarsten Keil 
373712b42dSKarsten Keil #include <linux/vmalloc.h>
383712b42dSKarsten Keil #include <linux/mISDNif.h>
39a5355c27SAndreas Eversberg #include <linux/in.h>
403712b42dSKarsten Keil #include "core.h"
415b834354SHannes Eder #include "l1oip.h"
423712b42dSKarsten Keil 
433712b42dSKarsten Keil /* definitions of codec. don't use calculations, code may run slower. */
443712b42dSKarsten Keil 
453712b42dSKarsten Keil static u8 *table_com;
463712b42dSKarsten Keil static u16 *table_dec;
473712b42dSKarsten Keil 
483712b42dSKarsten Keil 
493712b42dSKarsten Keil /* alaw -> ulaw */
503712b42dSKarsten Keil static u8 alaw_to_ulaw[256] =
513712b42dSKarsten Keil {
523712b42dSKarsten Keil 	0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
533712b42dSKarsten Keil 	0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
543712b42dSKarsten Keil 	0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
553712b42dSKarsten Keil 	0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
563712b42dSKarsten Keil 	0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
573712b42dSKarsten Keil 	0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
583712b42dSKarsten Keil 	0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
593712b42dSKarsten Keil 	0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
603712b42dSKarsten Keil 	0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
613712b42dSKarsten Keil 	0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
623712b42dSKarsten Keil 	0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
633712b42dSKarsten Keil 	0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
643712b42dSKarsten Keil 	0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
653712b42dSKarsten Keil 	0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
663712b42dSKarsten Keil 	0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
673712b42dSKarsten Keil 	0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
683712b42dSKarsten Keil 	0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
693712b42dSKarsten Keil 	0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
703712b42dSKarsten Keil 	0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
713712b42dSKarsten Keil 	0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
723712b42dSKarsten Keil 	0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
733712b42dSKarsten Keil 	0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
743712b42dSKarsten Keil 	0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
753712b42dSKarsten Keil 	0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
763712b42dSKarsten Keil 	0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
773712b42dSKarsten Keil 	0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
783712b42dSKarsten Keil 	0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
793712b42dSKarsten Keil 	0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
803712b42dSKarsten Keil 	0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
813712b42dSKarsten Keil 	0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
823712b42dSKarsten Keil 	0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
833712b42dSKarsten Keil 	0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
843712b42dSKarsten Keil };
853712b42dSKarsten Keil 
863712b42dSKarsten Keil /* ulaw -> alaw */
873712b42dSKarsten Keil static u8 ulaw_to_alaw[256] =
883712b42dSKarsten Keil {
893712b42dSKarsten Keil 	0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
903712b42dSKarsten Keil 	0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
913712b42dSKarsten Keil 	0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
923712b42dSKarsten Keil 	0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
933712b42dSKarsten Keil 	0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
943712b42dSKarsten Keil 	0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
953712b42dSKarsten Keil 	0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
963712b42dSKarsten Keil 	0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
973712b42dSKarsten Keil 	0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
983712b42dSKarsten Keil 	0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
993712b42dSKarsten Keil 	0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
1003712b42dSKarsten Keil 	0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
1013712b42dSKarsten Keil 	0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
1023712b42dSKarsten Keil 	0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
1033712b42dSKarsten Keil 	0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
1043712b42dSKarsten Keil 	0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
1053712b42dSKarsten Keil 	0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
1063712b42dSKarsten Keil 	0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
1073712b42dSKarsten Keil 	0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
1083712b42dSKarsten Keil 	0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
1093712b42dSKarsten Keil 	0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
1103712b42dSKarsten Keil 	0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
1113712b42dSKarsten Keil 	0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
1123712b42dSKarsten Keil 	0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
1133712b42dSKarsten Keil 	0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
1143712b42dSKarsten Keil 	0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
1153712b42dSKarsten Keil 	0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
1163712b42dSKarsten Keil 	0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
1173712b42dSKarsten Keil 	0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
1183712b42dSKarsten Keil 	0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
1193712b42dSKarsten Keil 	0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
1203712b42dSKarsten Keil 	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
1213712b42dSKarsten Keil };
1223712b42dSKarsten Keil 
1233712b42dSKarsten Keil /* alaw -> 4bit compression */
1243712b42dSKarsten Keil static u8 alaw_to_4bit[256] = {
1253712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1263712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1273712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1283712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1293712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1303712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1313712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1323712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1333712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1343712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1353712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
1363712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1373712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1383712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1393712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1403712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1413712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1423712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1433712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1443712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1453712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1463712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
1473712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1483712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1493712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1503712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1513712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1523712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1533712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1543712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1553712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1563712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1573712b42dSKarsten Keil };
1583712b42dSKarsten Keil 
1593712b42dSKarsten Keil /* 4bit -> alaw decompression */
1603712b42dSKarsten Keil static u8 _4bit_to_alaw[16] = {
1613712b42dSKarsten Keil 	0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
1623712b42dSKarsten Keil 	0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
1633712b42dSKarsten Keil };
1643712b42dSKarsten Keil 
1653712b42dSKarsten Keil /* ulaw -> 4bit compression */
1663712b42dSKarsten Keil static u8 ulaw_to_4bit[256] = {
1673712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1693712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1703712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1713712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1723712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1733712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1743712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1753712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
1763712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
1773712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
1783712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
1793712b42dSKarsten Keil 	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1803712b42dSKarsten Keil 	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
1813712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
1823712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
1833712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1843712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1853712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1863712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1873712b42dSKarsten Keil 	0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
1883712b42dSKarsten Keil 	0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
1893712b42dSKarsten Keil 	0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
1903712b42dSKarsten Keil 	0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
1913712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
1923712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
1933712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
1943712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
1953712b42dSKarsten Keil 	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
1963712b42dSKarsten Keil 	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
1973712b42dSKarsten Keil 	0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
1983712b42dSKarsten Keil 	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
1993712b42dSKarsten Keil };
2003712b42dSKarsten Keil 
2013712b42dSKarsten Keil /* 4bit -> ulaw decompression */
2023712b42dSKarsten Keil static u8 _4bit_to_ulaw[16] = {
2033712b42dSKarsten Keil 	0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
2043712b42dSKarsten Keil 	0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
2053712b42dSKarsten Keil };
2063712b42dSKarsten Keil 
2073712b42dSKarsten Keil 
2083712b42dSKarsten Keil /*
2093712b42dSKarsten Keil  * Compresses data to the result buffer
2103712b42dSKarsten Keil  * The result size must be at least half of the input buffer.
2113712b42dSKarsten Keil  * The number of samples also must be even!
2123712b42dSKarsten Keil  */
2133712b42dSKarsten Keil int
l1oip_law_to_4bit(u8 * data,int len,u8 * result,u32 * state)2143712b42dSKarsten Keil l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
2153712b42dSKarsten Keil {
2163712b42dSKarsten Keil 	int ii, i = 0, o = 0;
2173712b42dSKarsten Keil 
2183712b42dSKarsten Keil 	if (!len)
2193712b42dSKarsten Keil 		return 0;
2203712b42dSKarsten Keil 
2213712b42dSKarsten Keil 	/* send saved byte and first input byte */
2223712b42dSKarsten Keil 	if (*state) {
2233712b42dSKarsten Keil 		*result++ = table_com[(((*state) << 8) & 0xff00) | (*data++)];
2243712b42dSKarsten Keil 		len--;
2253712b42dSKarsten Keil 		o++;
2263712b42dSKarsten Keil 	}
2273712b42dSKarsten Keil 
2283712b42dSKarsten Keil 	ii = len >> 1;
2293712b42dSKarsten Keil 
2303712b42dSKarsten Keil 	while (i < ii) {
2313712b42dSKarsten Keil 		*result++ = table_com[(data[0]<<8) | (data[1])];
2323712b42dSKarsten Keil 		data += 2;
2333712b42dSKarsten Keil 		i++;
2343712b42dSKarsten Keil 		o++;
2353712b42dSKarsten Keil 	}
2363712b42dSKarsten Keil 
2373712b42dSKarsten Keil 	/* if len has an odd number, we save byte for next call */
2383712b42dSKarsten Keil 	if (len & 1)
2393712b42dSKarsten Keil 		*state = 0x100 + *data;
2403712b42dSKarsten Keil 	else
2413712b42dSKarsten Keil 		*state = 0;
2423712b42dSKarsten Keil 
2433712b42dSKarsten Keil 	return o;
2443712b42dSKarsten Keil }
2453712b42dSKarsten Keil 
2463712b42dSKarsten Keil /* Decompress data to the result buffer
2473712b42dSKarsten Keil  * The result size must be the number of sample in packet. (2 * input data)
2483712b42dSKarsten Keil  * The number of samples in the result are even!
2493712b42dSKarsten Keil  */
2503712b42dSKarsten Keil int
l1oip_4bit_to_law(u8 * data,int len,u8 * result)2513712b42dSKarsten Keil l1oip_4bit_to_law(u8 *data, int len, u8 *result)
2523712b42dSKarsten Keil {
2533712b42dSKarsten Keil 	int i = 0;
2543712b42dSKarsten Keil 	u16 r;
2553712b42dSKarsten Keil 
2563712b42dSKarsten Keil 	while (i < len) {
2573712b42dSKarsten Keil 		r = table_dec[*data++];
2583712b42dSKarsten Keil 		*result++ = r >> 8;
2593712b42dSKarsten Keil 		*result++ = r;
2603712b42dSKarsten Keil 		i++;
2613712b42dSKarsten Keil 	}
2623712b42dSKarsten Keil 
2633712b42dSKarsten Keil 	return len << 1;
2643712b42dSKarsten Keil }
2653712b42dSKarsten Keil 
2663712b42dSKarsten Keil 
2673712b42dSKarsten Keil /*
2683712b42dSKarsten Keil  * law conversion
2693712b42dSKarsten Keil  */
2703712b42dSKarsten Keil int
l1oip_alaw_to_ulaw(u8 * data,int len,u8 * result)2713712b42dSKarsten Keil l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
2723712b42dSKarsten Keil {
2733712b42dSKarsten Keil 	int i = 0;
2743712b42dSKarsten Keil 
2753712b42dSKarsten Keil 	while (i < len) {
2763712b42dSKarsten Keil 		*result++ = alaw_to_ulaw[*data++];
2773712b42dSKarsten Keil 		i++;
2783712b42dSKarsten Keil 	}
2793712b42dSKarsten Keil 
2803712b42dSKarsten Keil 	return len;
2813712b42dSKarsten Keil }
2823712b42dSKarsten Keil 
2833712b42dSKarsten Keil int
l1oip_ulaw_to_alaw(u8 * data,int len,u8 * result)2843712b42dSKarsten Keil l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
2853712b42dSKarsten Keil {
2863712b42dSKarsten Keil 	int i = 0;
2873712b42dSKarsten Keil 
2883712b42dSKarsten Keil 	while (i < len) {
2893712b42dSKarsten Keil 		*result++ = ulaw_to_alaw[*data++];
2903712b42dSKarsten Keil 		i++;
2913712b42dSKarsten Keil 	}
2923712b42dSKarsten Keil 
2933712b42dSKarsten Keil 	return len;
2943712b42dSKarsten Keil }
2953712b42dSKarsten Keil 
2963712b42dSKarsten Keil 
2973712b42dSKarsten Keil /*
2983712b42dSKarsten Keil  * generate/free compression and decompression table
2993712b42dSKarsten Keil  */
3003712b42dSKarsten Keil void
l1oip_4bit_free(void)3013712b42dSKarsten Keil l1oip_4bit_free(void)
3023712b42dSKarsten Keil {
3033712b42dSKarsten Keil 	vfree(table_dec);
3043712b42dSKarsten Keil 	vfree(table_com);
3053712b42dSKarsten Keil 	table_com = NULL;
3063712b42dSKarsten Keil 	table_dec = NULL;
3073712b42dSKarsten Keil }
3083712b42dSKarsten Keil 
3093712b42dSKarsten Keil int
l1oip_4bit_alloc(int ulaw)3103712b42dSKarsten Keil l1oip_4bit_alloc(int ulaw)
3113712b42dSKarsten Keil {
3123712b42dSKarsten Keil 	int i1, i2, c, sample;
3133712b42dSKarsten Keil 
3143712b42dSKarsten Keil 	/* in case, it is called again */
3153712b42dSKarsten Keil 	if (table_dec)
3163712b42dSKarsten Keil 		return 0;
3173712b42dSKarsten Keil 
3183712b42dSKarsten Keil 	/* alloc conversion tables */
3191ac4594dSJoe Perches 	table_com = vzalloc(65536);
3201ac4594dSJoe Perches 	table_dec = vzalloc(512);
32124ec68fbSAlexey Zaytsev 	if (!table_com || !table_dec) {
3223712b42dSKarsten Keil 		l1oip_4bit_free();
3233712b42dSKarsten Keil 		return -ENOMEM;
3243712b42dSKarsten Keil 	}
3253712b42dSKarsten Keil 	/* generate compression table */
3263712b42dSKarsten Keil 	i1 = 0;
3273712b42dSKarsten Keil 	while (i1 < 256) {
3283712b42dSKarsten Keil 		if (ulaw)
3293712b42dSKarsten Keil 			c = ulaw_to_4bit[i1];
3303712b42dSKarsten Keil 		else
3313712b42dSKarsten Keil 			c = alaw_to_4bit[i1];
3323712b42dSKarsten Keil 		i2 = 0;
3333712b42dSKarsten Keil 		while (i2 < 256) {
3343712b42dSKarsten Keil 			table_com[(i1 << 8) | i2] |= (c << 4);
3353712b42dSKarsten Keil 			table_com[(i2 << 8) | i1] |= c;
3363712b42dSKarsten Keil 			i2++;
3373712b42dSKarsten Keil 		}
3383712b42dSKarsten Keil 		i1++;
3393712b42dSKarsten Keil 	}
3403712b42dSKarsten Keil 
3413712b42dSKarsten Keil 	/* generate decompression table */
3423712b42dSKarsten Keil 	i1 = 0;
3433712b42dSKarsten Keil 	while (i1 < 16) {
3443712b42dSKarsten Keil 		if (ulaw)
3453712b42dSKarsten Keil 			sample = _4bit_to_ulaw[i1];
3463712b42dSKarsten Keil 		else
3473712b42dSKarsten Keil 			sample = _4bit_to_alaw[i1];
3483712b42dSKarsten Keil 		i2 = 0;
3493712b42dSKarsten Keil 		while (i2 < 16) {
3503712b42dSKarsten Keil 			table_dec[(i1 << 4) | i2] |= (sample << 8);
3513712b42dSKarsten Keil 			table_dec[(i2 << 4) | i1] |= sample;
3523712b42dSKarsten Keil 			i2++;
3533712b42dSKarsten Keil 		}
3543712b42dSKarsten Keil 		i1++;
3553712b42dSKarsten Keil 	}
3563712b42dSKarsten Keil 
3573712b42dSKarsten Keil 	return 0;
3583712b42dSKarsten Keil }
359