This source file includes following definitions.
- rsnd_ctu_activation
- rsnd_ctu_halt
- rsnd_ctu_probe_
- rsnd_ctu_value_init
- rsnd_ctu_value_reset
- rsnd_ctu_init
- rsnd_ctu_quit
- rsnd_ctu_pcm_new
- rsnd_ctu_id
- rsnd_ctu_id_sub
- rsnd_ctu_mod_get
- rsnd_ctu_probe
- rsnd_ctu_remove
1
2
3
4
5
6
7 #include "rsnd.h"
8
9 #define CTU_NAME_SIZE 16
10 #define CTU_NAME "ctu"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 struct rsnd_ctu {
73 struct rsnd_mod mod;
74 struct rsnd_kctrl_cfg_m pass;
75 struct rsnd_kctrl_cfg_m sv[4];
76 struct rsnd_kctrl_cfg_s reset;
77 int channels;
78 u32 flags;
79 };
80
81 #define KCTRL_INITIALIZED (1 << 0)
82
83 #define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
84 #define for_each_rsnd_ctu(pos, priv, i) \
85 for ((i) = 0; \
86 ((i) < rsnd_ctu_nr(priv)) && \
87 ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \
88 i++)
89
90 #define rsnd_mod_to_ctu(_mod) \
91 container_of((_mod), struct rsnd_ctu, mod)
92
93 #define rsnd_ctu_get(priv, id) ((struct rsnd_ctu *)(priv->ctu) + id)
94
95 static void rsnd_ctu_activation(struct rsnd_mod *mod)
96 {
97 rsnd_mod_write(mod, CTU_SWRSR, 0);
98 rsnd_mod_write(mod, CTU_SWRSR, 1);
99 }
100
101 static void rsnd_ctu_halt(struct rsnd_mod *mod)
102 {
103 rsnd_mod_write(mod, CTU_CTUIR, 1);
104 rsnd_mod_write(mod, CTU_SWRSR, 0);
105 }
106
107 static int rsnd_ctu_probe_(struct rsnd_mod *mod,
108 struct rsnd_dai_stream *io,
109 struct rsnd_priv *priv)
110 {
111 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
112 }
113
114 static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
115 struct rsnd_mod *mod)
116 {
117 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
118 u32 cpmdr = 0;
119 u32 scmdr = 0;
120 int i, j;
121
122 for (i = 0; i < RSND_MAX_CHANNELS; i++) {
123 u32 val = rsnd_kctrl_valm(ctu->pass, i);
124
125 cpmdr |= val << (28 - (i * 4));
126
127 if ((val > 0x8) && (scmdr < (val - 0x8)))
128 scmdr = val - 0x8;
129 }
130
131 rsnd_mod_write(mod, CTU_CTUIR, 1);
132
133 rsnd_mod_write(mod, CTU_ADINR, rsnd_runtime_channel_original(io));
134
135 rsnd_mod_write(mod, CTU_CPMDR, cpmdr);
136
137 rsnd_mod_write(mod, CTU_SCMDR, scmdr);
138
139 for (i = 0; i < 4; i++) {
140
141 if (i >= scmdr)
142 break;
143
144 for (j = 0; j < RSND_MAX_CHANNELS; j++)
145 rsnd_mod_write(mod, CTU_SVxxR(i, j), rsnd_kctrl_valm(ctu->sv[i], j));
146 }
147
148 rsnd_mod_write(mod, CTU_CTUIR, 0);
149 }
150
151 static void rsnd_ctu_value_reset(struct rsnd_dai_stream *io,
152 struct rsnd_mod *mod)
153 {
154 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
155 int i;
156
157 if (!rsnd_kctrl_vals(ctu->reset))
158 return;
159
160 for (i = 0; i < RSND_MAX_CHANNELS; i++) {
161 rsnd_kctrl_valm(ctu->pass, i) = 0;
162 rsnd_kctrl_valm(ctu->sv[0], i) = 0;
163 rsnd_kctrl_valm(ctu->sv[1], i) = 0;
164 rsnd_kctrl_valm(ctu->sv[2], i) = 0;
165 rsnd_kctrl_valm(ctu->sv[3], i) = 0;
166 }
167 rsnd_kctrl_vals(ctu->reset) = 0;
168 }
169
170 static int rsnd_ctu_init(struct rsnd_mod *mod,
171 struct rsnd_dai_stream *io,
172 struct rsnd_priv *priv)
173 {
174 rsnd_mod_power_on(mod);
175
176 rsnd_ctu_activation(mod);
177
178 rsnd_ctu_value_init(io, mod);
179
180 return 0;
181 }
182
183 static int rsnd_ctu_quit(struct rsnd_mod *mod,
184 struct rsnd_dai_stream *io,
185 struct rsnd_priv *priv)
186 {
187 rsnd_ctu_halt(mod);
188
189 rsnd_mod_power_off(mod);
190
191 return 0;
192 }
193
194 static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
195 struct rsnd_dai_stream *io,
196 struct snd_soc_pcm_runtime *rtd)
197 {
198 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
199 int ret;
200
201 if (rsnd_flags_has(ctu, KCTRL_INITIALIZED))
202 return 0;
203
204
205 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU Pass",
206 rsnd_kctrl_accept_anytime,
207 NULL,
208 &ctu->pass, RSND_MAX_CHANNELS,
209 0xC);
210
211
212 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV0",
213 rsnd_kctrl_accept_anytime,
214 NULL,
215 &ctu->sv[0], RSND_MAX_CHANNELS,
216 0x00FFFFFF);
217 if (ret < 0)
218 return ret;
219
220
221 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV1",
222 rsnd_kctrl_accept_anytime,
223 NULL,
224 &ctu->sv[1], RSND_MAX_CHANNELS,
225 0x00FFFFFF);
226 if (ret < 0)
227 return ret;
228
229
230 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV2",
231 rsnd_kctrl_accept_anytime,
232 NULL,
233 &ctu->sv[2], RSND_MAX_CHANNELS,
234 0x00FFFFFF);
235 if (ret < 0)
236 return ret;
237
238
239 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV3",
240 rsnd_kctrl_accept_anytime,
241 NULL,
242 &ctu->sv[3], RSND_MAX_CHANNELS,
243 0x00FFFFFF);
244 if (ret < 0)
245 return ret;
246
247
248 ret = rsnd_kctrl_new_s(mod, io, rtd, "CTU Reset",
249 rsnd_kctrl_accept_anytime,
250 rsnd_ctu_value_reset,
251 &ctu->reset, 1);
252
253 rsnd_flags_set(ctu, KCTRL_INITIALIZED);
254
255 return ret;
256 }
257
258 static int rsnd_ctu_id(struct rsnd_mod *mod)
259 {
260
261
262
263
264 return mod->id / 4;
265 }
266
267 static int rsnd_ctu_id_sub(struct rsnd_mod *mod)
268 {
269
270
271
272
273 return mod->id % 4;
274 }
275
276 static struct rsnd_mod_ops rsnd_ctu_ops = {
277 .name = CTU_NAME,
278 .probe = rsnd_ctu_probe_,
279 .init = rsnd_ctu_init,
280 .quit = rsnd_ctu_quit,
281 .pcm_new = rsnd_ctu_pcm_new,
282 .get_status = rsnd_mod_get_status,
283 .id = rsnd_ctu_id,
284 .id_sub = rsnd_ctu_id_sub,
285 .id_cmd = rsnd_mod_id_raw,
286 };
287
288 struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
289 {
290 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
291 id = 0;
292
293 return rsnd_mod_get(rsnd_ctu_get(priv, id));
294 }
295
296 int rsnd_ctu_probe(struct rsnd_priv *priv)
297 {
298 struct device_node *node;
299 struct device_node *np;
300 struct device *dev = rsnd_priv_to_dev(priv);
301 struct rsnd_ctu *ctu;
302 struct clk *clk;
303 char name[CTU_NAME_SIZE];
304 int i, nr, ret;
305
306
307 if (rsnd_is_gen1(priv))
308 return 0;
309
310 node = rsnd_ctu_of_node(priv);
311 if (!node)
312 return 0;
313
314 nr = of_get_child_count(node);
315 if (!nr) {
316 ret = -EINVAL;
317 goto rsnd_ctu_probe_done;
318 }
319
320 ctu = devm_kcalloc(dev, nr, sizeof(*ctu), GFP_KERNEL);
321 if (!ctu) {
322 ret = -ENOMEM;
323 goto rsnd_ctu_probe_done;
324 }
325
326 priv->ctu_nr = nr;
327 priv->ctu = ctu;
328
329 i = 0;
330 ret = 0;
331 for_each_child_of_node(node, np) {
332 ctu = rsnd_ctu_get(priv, i);
333
334
335
336
337
338 snprintf(name, CTU_NAME_SIZE, "%s.%d",
339 CTU_NAME, i / 4);
340
341 clk = devm_clk_get(dev, name);
342 if (IS_ERR(clk)) {
343 ret = PTR_ERR(clk);
344 of_node_put(np);
345 goto rsnd_ctu_probe_done;
346 }
347
348 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
349 clk, RSND_MOD_CTU, i);
350 if (ret) {
351 of_node_put(np);
352 goto rsnd_ctu_probe_done;
353 }
354
355 i++;
356 }
357
358
359 rsnd_ctu_probe_done:
360 of_node_put(node);
361
362 return ret;
363 }
364
365 void rsnd_ctu_remove(struct rsnd_priv *priv)
366 {
367 struct rsnd_ctu *ctu;
368 int i;
369
370 for_each_rsnd_ctu(ctu, priv, i) {
371 rsnd_mod_quit(rsnd_mod_get(ctu));
372 }
373 }