diff options
Diffstat (limited to 'drivers/isdn/mISDN/dsp_hwec.c')
-rw-r--r-- | drivers/isdn/mISDN/dsp_hwec.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/drivers/isdn/mISDN/dsp_hwec.c b/drivers/isdn/mISDN/dsp_hwec.c new file mode 100644 index 000000000000..eb892d9dd5c6 --- /dev/null +++ b/drivers/isdn/mISDN/dsp_hwec.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * dsp_hwec.c: | ||
3 | * builtin mISDN dsp pipeline element for enabling the hw echocanceller | ||
4 | * | ||
5 | * Copyright (C) 2007, Nadi Sarrar | ||
6 | * | ||
7 | * Nadi Sarrar <nadi@beronet.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along with | ||
20 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
21 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * | ||
23 | * The full GNU General Public License is included in this distribution in the | ||
24 | * file called LICENSE. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/mISDNdsp.h> | ||
31 | #include <linux/mISDNif.h> | ||
32 | #include "core.h" | ||
33 | #include "dsp.h" | ||
34 | #include "dsp_hwec.h" | ||
35 | |||
36 | static struct mISDN_dsp_element_arg args[] = { | ||
37 | { "deftaps", "128", "Set the number of taps of cancellation." }, | ||
38 | }; | ||
39 | |||
40 | static struct mISDN_dsp_element dsp_hwec_p = { | ||
41 | .name = "hwec", | ||
42 | .new = NULL, | ||
43 | .free = NULL, | ||
44 | .process_tx = NULL, | ||
45 | .process_rx = NULL, | ||
46 | .num_args = sizeof(args) / sizeof(struct mISDN_dsp_element_arg), | ||
47 | .args = args, | ||
48 | }; | ||
49 | struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p; | ||
50 | |||
51 | void dsp_hwec_enable(struct dsp *dsp, const char *arg) | ||
52 | { | ||
53 | int deftaps = 128, | ||
54 | len; | ||
55 | struct mISDN_ctrl_req cq; | ||
56 | |||
57 | if (!dsp) { | ||
58 | printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n", | ||
59 | __func__); | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | if (!arg) | ||
64 | goto _do; | ||
65 | |||
66 | len = strlen(arg); | ||
67 | if (!len) | ||
68 | goto _do; | ||
69 | |||
70 | { | ||
71 | char _dup[len + 1]; | ||
72 | char *dup, *tok, *name, *val; | ||
73 | int tmp; | ||
74 | |||
75 | strcpy(_dup, arg); | ||
76 | dup = _dup; | ||
77 | |||
78 | while ((tok = strsep(&dup, ","))) { | ||
79 | if (!strlen(tok)) | ||
80 | continue; | ||
81 | name = strsep(&tok, "="); | ||
82 | val = tok; | ||
83 | |||
84 | if (!val) | ||
85 | continue; | ||
86 | |||
87 | if (!strcmp(name, "deftaps")) { | ||
88 | if (sscanf(val, "%d", &tmp) == 1) | ||
89 | deftaps = tmp; | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
94 | _do: | ||
95 | printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n", | ||
96 | __func__, deftaps); | ||
97 | memset(&cq, 0, sizeof(cq)); | ||
98 | cq.op = MISDN_CTRL_HFC_ECHOCAN_ON; | ||
99 | cq.p1 = deftaps; | ||
100 | if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { | ||
101 | printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", | ||
102 | __func__); | ||
103 | return; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void dsp_hwec_disable(struct dsp *dsp) | ||
108 | { | ||
109 | struct mISDN_ctrl_req cq; | ||
110 | |||
111 | if (!dsp) { | ||
112 | printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n", | ||
113 | __func__); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | printk(KERN_DEBUG "%s: disabling hwec\n", __func__); | ||
118 | memset(&cq, 0, sizeof(cq)); | ||
119 | cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF; | ||
120 | if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) { | ||
121 | printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n", | ||
122 | __func__); | ||
123 | return; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | int dsp_hwec_init(void) | ||
128 | { | ||
129 | mISDN_dsp_element_register(dsp_hwec); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | void dsp_hwec_exit(void) | ||
135 | { | ||
136 | mISDN_dsp_element_unregister(dsp_hwec); | ||
137 | } | ||
138 | |||