dsp_hwec.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * dsp_hwec.c:
  4. * builtin mISDN dsp pipeline element for enabling the hw echocanceller
  5. *
  6. * Copyright (C) 2007, Nadi Sarrar
  7. *
  8. * Nadi Sarrar <[email protected]>
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/string.h>
  12. #include <linux/mISDNdsp.h>
  13. #include <linux/mISDNif.h>
  14. #include "core.h"
  15. #include "dsp.h"
  16. #include "dsp_hwec.h"
  17. static struct mISDN_dsp_element_arg args[] = {
  18. { "deftaps", "128", "Set the number of taps of cancellation." },
  19. };
  20. static struct mISDN_dsp_element dsp_hwec_p = {
  21. .name = "hwec",
  22. .new = NULL,
  23. .free = NULL,
  24. .process_tx = NULL,
  25. .process_rx = NULL,
  26. .num_args = ARRAY_SIZE(args),
  27. .args = args,
  28. };
  29. struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p;
  30. void dsp_hwec_enable(struct dsp *dsp, const char *arg)
  31. {
  32. int deftaps = 128,
  33. len;
  34. struct mISDN_ctrl_req cq;
  35. if (!dsp) {
  36. printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n",
  37. __func__);
  38. return;
  39. }
  40. if (!arg)
  41. goto _do;
  42. len = strlen(arg);
  43. if (!len)
  44. goto _do;
  45. {
  46. char *dup, *tok, *name, *val;
  47. int tmp;
  48. dup = kstrdup(arg, GFP_ATOMIC);
  49. if (!dup)
  50. return;
  51. while ((tok = strsep(&dup, ","))) {
  52. if (!strlen(tok))
  53. continue;
  54. name = strsep(&tok, "=");
  55. val = tok;
  56. if (!val)
  57. continue;
  58. if (!strcmp(name, "deftaps")) {
  59. if (sscanf(val, "%d", &tmp) == 1)
  60. deftaps = tmp;
  61. }
  62. }
  63. kfree(dup);
  64. }
  65. _do:
  66. printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n",
  67. __func__, deftaps);
  68. memset(&cq, 0, sizeof(cq));
  69. cq.op = MISDN_CTRL_HFC_ECHOCAN_ON;
  70. cq.p1 = deftaps;
  71. if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
  72. printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
  73. __func__);
  74. return;
  75. }
  76. }
  77. void dsp_hwec_disable(struct dsp *dsp)
  78. {
  79. struct mISDN_ctrl_req cq;
  80. if (!dsp) {
  81. printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n",
  82. __func__);
  83. return;
  84. }
  85. printk(KERN_DEBUG "%s: disabling hwec\n", __func__);
  86. memset(&cq, 0, sizeof(cq));
  87. cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF;
  88. if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
  89. printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
  90. __func__);
  91. return;
  92. }
  93. }
  94. int dsp_hwec_init(void)
  95. {
  96. mISDN_dsp_element_register(dsp_hwec);
  97. return 0;
  98. }
  99. void dsp_hwec_exit(void)
  100. {
  101. mISDN_dsp_element_unregister(dsp_hwec);
  102. }