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 <nadi@beronet.com> 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/string.h> 13 #include <linux/mISDNdsp.h> 14 #include <linux/mISDNif.h> 15 #include "core.h" 16 #include "dsp.h" 17 #include "dsp_hwec.h" 18 19 static struct mISDN_dsp_element_arg args[] = { 20 { "deftaps", "128", "Set the number of taps of cancellation." }, 21 }; 22 23 static struct mISDN_dsp_element dsp_hwec_p = { 24 .name = "hwec", 25 .new = NULL, 26 .free = NULL, 27 .process_tx = NULL, 28 .process_rx = NULL, 29 .num_args = ARRAY_SIZE(args), 30 .args = args, 31 }; 32 struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p; 33 34 void dsp_hwec_enable(struct dsp *dsp, const char *arg) 35 { 36 int deftaps = 128, 37 len; 38 struct mISDN_ctrl_req cq; 39 40 if (!dsp) { 41 printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n", 42 __func__); 43 return; 44 } 45 46 if (!arg) 47 goto _do; 48 49 len = strlen(arg); 50 if (!len) 51 goto _do; 52 53 { 54 char *dup, *tok, *name, *val; 55 int tmp; 56 57 dup = kstrdup(arg, GFP_ATOMIC); 58 if (!dup) 59 return; 60 61 while ((tok = strsep(&dup, ","))) { 62 if (!strlen(tok)) 63 continue; 64 name = strsep(&tok, "="); 65 val = tok; 66 67 if (!val) 68 continue; 69 70 if (!strcmp(name, "deftaps")) { 71 if (sscanf(val, "%d", &tmp) == 1) 72 deftaps = tmp; 73 } 74 } 75 76 kfree(dup); 77 } 78 79 _do: 80 printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n", 81 __func__, deftaps); 82 memset(&cq, 0, sizeof(cq)); 83 cq.op = MISDN_CTRL_HFC_ECHOCAN_ON; 84 cq.p1 = deftaps; 85 if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { 86 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", 87 __func__); 88 return; 89 } 90 } 91 92 void dsp_hwec_disable(struct dsp *dsp) 93 { 94 struct mISDN_ctrl_req cq; 95 96 if (!dsp) { 97 printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n", 98 __func__); 99 return; 100 } 101 102 printk(KERN_DEBUG "%s: disabling hwec\n", __func__); 103 memset(&cq, 0, sizeof(cq)); 104 cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF; 105 if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { 106 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", 107 __func__); 108 return; 109 } 110 } 111 112 int dsp_hwec_init(void) 113 { 114 mISDN_dsp_element_register(dsp_hwec); 115 116 return 0; 117 } 118 119 void dsp_hwec_exit(void) 120 { 121 mISDN_dsp_element_unregister(dsp_hwec); 122 } 123