apec.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /*
  2. * AP400 Echo Cancelation Hardware support
  3. *
  4. * Written by Wagner Gegler <aligera@aligera.com.br>
  5. *
  6. * Based on previous work written by Mark Spencer <markster@digium.com>
  7. *
  8. * Copyright (C) 2005-2006 Digium, Inc.
  9. *
  10. * Mark Spencer <markster@digium.com>
  11. *
  12. * All Rights Reserved
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27. *
  28. */
  29. #include <linux/slab.h>
  30. #include <linux/vmalloc.h>
  31. #include <linux/string.h>
  32. #include <linux/time.h>
  33. #include <linux/version.h>
  34. #include <linux/delay.h>
  35. #include "apec.h"
  36. #include "oct6100api/oct6100_api.h"
  37. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
  38. #include <linux/config.h>
  39. #else
  40. #include <linux/autoconf.h>
  41. #endif
  42. /* API for Octasic access */
  43. UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
  44. {
  45. /* Why couldn't they just take a timeval like everyone else? */
  46. struct timeval tv;
  47. unsigned long long total_usecs;
  48. unsigned int mask = ~0;
  49. do_gettimeofday(&tv);
  50. total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
  51. (((unsigned long long)(tv.tv_usec)));
  52. f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
  53. f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
  54. return cOCT6100_ERR_OK;
  55. }
  56. UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
  57. {
  58. memset(f_pAddress, f_ulPattern, f_ulLength);
  59. return cOCT6100_ERR_OK;
  60. }
  61. UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
  62. {
  63. memcpy(f_pDestination, f_pSource, f_ulLength);
  64. return cOCT6100_ERR_OK;
  65. }
  66. UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
  67. {
  68. return cOCT6100_ERR_OK;
  69. }
  70. UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
  71. {
  72. #ifdef OCTASIC_DEBUG
  73. printk("I should never be called! (destroy serialize object)\n");
  74. #endif
  75. return cOCT6100_ERR_OK;
  76. }
  77. UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
  78. {
  79. /* Not needed */
  80. return cOCT6100_ERR_OK;
  81. }
  82. UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
  83. {
  84. /* Not needed */
  85. return cOCT6100_ERR_OK;
  86. }
  87. UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
  88. {
  89. oct_write(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
  90. return cOCT6100_ERR_OK;
  91. }
  92. UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
  93. {
  94. unsigned int x;
  95. for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
  96. oct_write(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
  97. }
  98. return cOCT6100_ERR_OK;
  99. }
  100. UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
  101. {
  102. unsigned int x;
  103. for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
  104. oct_write(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
  105. }
  106. return cOCT6100_ERR_OK;
  107. }
  108. UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
  109. {
  110. *(f_pReadParams->pusReadData) = oct_read(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
  111. return cOCT6100_ERR_OK;
  112. }
  113. UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
  114. {
  115. unsigned int x;
  116. for (x=0;x<f_pBurstParams->ulReadLength;x++) {
  117. f_pBurstParams->pusReadData[x] = oct_read(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
  118. }
  119. return cOCT6100_ERR_OK;
  120. }
  121. #if 0
  122. #define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
  123. #else
  124. #define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
  125. #endif
  126. struct apec_s {
  127. tPOCT6100_INSTANCE_API pApiInstance;
  128. UINT32 aulEchoChanHndl[128];
  129. int chanflags[128];
  130. int ecmode[128];
  131. int numchans;
  132. };
  133. #define FLAG_DTMF (1 << 0)
  134. #define FLAG_MUTE (1 << 1)
  135. #define FLAG_ECHO (1 << 2)
  136. static void apec_setecmode(struct apec_s *apec, int channel, int mode)
  137. {
  138. tOCT6100_CHANNEL_MODIFY *modify;
  139. UINT32 ulResult;
  140. if (apec->ecmode[channel] == mode)
  141. return;
  142. modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
  143. if (!modify) {
  144. printk("APEC: Unable to allocate memory for setec!\n");
  145. return;
  146. }
  147. Oct6100ChannelModifyDef(modify);
  148. modify->ulEchoOperationMode = mode;
  149. modify->ulChannelHndl = apec->aulEchoChanHndl[channel];
  150. ulResult = Oct6100ChannelModify(apec->pApiInstance, modify);
  151. if (ulResult != GENERIC_OK) {
  152. printk("Failed to apply echo can changes on channel %d!\n", channel);
  153. } else {
  154. #ifdef OCTASIC_DEBUG
  155. printk("Echo can on channel %d set to %d\n", channel, mode);
  156. #endif
  157. apec->ecmode[channel] = mode;
  158. }
  159. kfree(modify);
  160. }
  161. void apec_setec(struct apec_s *apec, int channel, int eclen)
  162. {
  163. if (eclen) {
  164. apec->chanflags[channel] |= FLAG_ECHO;
  165. apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
  166. apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
  167. } else {
  168. apec->chanflags[channel] &= ~FLAG_ECHO;
  169. if (apec->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
  170. apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
  171. apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
  172. } else
  173. apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
  174. }
  175. printk("APEC: Setting EC on channel %d to %d\n", channel, eclen);
  176. }
  177. int apec_checkirq(struct apec_s *apec)
  178. {
  179. tOCT6100_INTERRUPT_FLAGS InterruptFlags;
  180. Oct6100InterruptServiceRoutineDef(&InterruptFlags);
  181. Oct6100InterruptServiceRoutine(apec->pApiInstance, &InterruptFlags);
  182. return InterruptFlags.fToneEventsPending ? 1 : 0;
  183. }
  184. unsigned int apec_capacity_get(void *wc)
  185. {
  186. UINT32 ulResult;
  187. tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
  188. Oct6100ApiGetCapacityPinsDef(&CapacityPins);
  189. CapacityPins.pProcessContext = wc;
  190. CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
  191. CapacityPins.fEnableMemClkOut = TRUE;
  192. CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
  193. ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
  194. if (ulResult != cOCT6100_ERR_OK) {
  195. printk("Failed to get chip capacity, code %08x!\n", ulResult);
  196. return 0;
  197. }
  198. return CapacityPins.ulCapacityValue;
  199. }
  200. struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
  201. {
  202. tOCT6100_CHIP_OPEN *ChipOpen;
  203. tOCT6100_GET_INSTANCE_SIZE InstanceSize;
  204. tOCT6100_CHANNEL_OPEN *ChannelOpen;
  205. UINT32 ulResult;
  206. struct apec_s *apec;
  207. int x, law;
  208. #ifdef CONFIG_4KSTACKS
  209. unsigned long flags;
  210. #endif
  211. if (!(apec = kmalloc(sizeof(struct apec_s), GFP_KERNEL)))
  212. return NULL;
  213. memset(apec, 0, sizeof(struct apec_s));
  214. if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
  215. kfree(apec);
  216. return NULL;
  217. }
  218. memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
  219. if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
  220. kfree(apec);
  221. kfree(ChipOpen);
  222. return NULL;
  223. }
  224. memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
  225. for (x=0;x<128;x++)
  226. apec->ecmode[x] = -1;
  227. apec->numchans = numspans * 32;
  228. printk("APEC: echo cancellation for %d channels\n", apec->numchans);
  229. Oct6100ChipOpenDef(ChipOpen);
  230. /* Setup Chip Open Parameters */
  231. ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
  232. Oct6100GetInstanceSizeDef(&InstanceSize);
  233. ChipOpen->pProcessContext = wc;
  234. ChipOpen->pbyImageFile = firmware->data;
  235. ChipOpen->ulImageSize = firmware->size;
  236. ChipOpen->fEnableMemClkOut = TRUE;
  237. ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
  238. ChipOpen->ulMaxChannels = apec->numchans;
  239. ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
  240. ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
  241. ChipOpen->ulNumMemoryChips = 1;
  242. ChipOpen->ulMaxTdmStreams = 4;
  243. ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
  244. ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
  245. #if 0
  246. ChipOpen->fEnableAcousticEcho = TRUE;
  247. #endif
  248. ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
  249. if (ulResult != cOCT6100_ERR_OK) {
  250. printk("Failed to get instance size, code %08x!\n", ulResult);
  251. kfree(apec);
  252. return NULL;
  253. }
  254. apec->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
  255. if (!apec->pApiInstance) {
  256. printk("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
  257. kfree(apec);
  258. kfree(ChipOpen);
  259. kfree(ChannelOpen);
  260. return NULL;
  261. }
  262. /* I don't know what to curse more in this comment, the problems caused by
  263. * the 4K kernel stack limit change or the octasic API for being so darn
  264. * stack unfriendly. Stupid, stupid, stupid. So we disable IRQs so we
  265. * don't run the risk of overflowing the stack while we initialize the
  266. * octasic. */
  267. #ifdef CONFIG_4KSTACKS
  268. local_irq_save(flags);
  269. #endif
  270. ulResult = Oct6100ChipOpen(apec->pApiInstance, ChipOpen);
  271. if (ulResult != cOCT6100_ERR_OK) {
  272. printk("Failed to open chip, code %08x!\n", ulResult);
  273. #ifdef CONFIG_4KSTACKS
  274. local_irq_restore(flags);
  275. #endif
  276. kfree(apec);
  277. kfree(ChipOpen);
  278. kfree(ChannelOpen);
  279. return NULL;
  280. }
  281. for (x=0; x < 128; x++) {
  282. /* execute this loop always on 4 span cards but
  283. * on 2 span cards only execute for the channels related to our spans */
  284. if ((x & 0x3) < numspans) {
  285. /* span timeslots are interleaved 12341234...
  286. * therefore, the lower 2 bits tell us which span this
  287. * timeslot/channel
  288. */
  289. if (isalaw[x & 0x03])
  290. law = cOCT6100_PCM_A_LAW;
  291. else
  292. law = cOCT6100_PCM_U_LAW;
  293. Oct6100ChannelOpenDef(ChannelOpen);
  294. ChannelOpen->pulChannelHndl = &apec->aulEchoChanHndl[x];
  295. ChannelOpen->ulUserChanId = x;
  296. ChannelOpen->TdmConfig.ulRinPcmLaw = law;
  297. ChannelOpen->TdmConfig.ulRinStream = 0;
  298. ChannelOpen->TdmConfig.ulRinTimeslot = x;
  299. ChannelOpen->TdmConfig.ulSinPcmLaw = law;
  300. ChannelOpen->TdmConfig.ulSinStream = 1;
  301. ChannelOpen->TdmConfig.ulSinTimeslot = x;
  302. ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
  303. ChannelOpen->TdmConfig.ulSoutStream = 2;
  304. ChannelOpen->TdmConfig.ulSoutTimeslot = x;
  305. ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
  306. ChannelOpen->TdmConfig.ulRoutStream = 3;
  307. ChannelOpen->TdmConfig.ulRoutTimeslot = x;
  308. ChannelOpen->VqeConfig.fEnableNlp = TRUE;
  309. ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
  310. ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
  311. ChannelOpen->fEnableToneDisabler = TRUE;
  312. ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
  313. ulResult = Oct6100ChannelOpen(apec->pApiInstance, ChannelOpen);
  314. if (ulResult != GENERIC_OK) {
  315. printk("Failed to open channel %d!\n", x);
  316. }
  317. }
  318. }
  319. #ifdef CONFIG_4KSTACKS
  320. local_irq_restore(flags);
  321. #endif
  322. kfree(ChipOpen);
  323. kfree(ChannelOpen);
  324. return apec;
  325. }
  326. void apec_release(struct apec_s *apec)
  327. {
  328. UINT32 ulResult;
  329. tOCT6100_CHIP_CLOSE ChipClose;
  330. Oct6100ChipCloseDef(&ChipClose);
  331. ulResult = Oct6100ChipClose(apec->pApiInstance, &ChipClose);
  332. if (ulResult != cOCT6100_ERR_OK) {
  333. printk("Failed to close chip, code %08x!\n", ulResult);
  334. }
  335. vfree(apec->pApiInstance);
  336. kfree(apec);
  337. printk(KERN_INFO "APEC: Releasing...\n");
  338. }