.. | .. |
---|
72 | 72 | struct rsnd_ctu { |
---|
73 | 73 | struct rsnd_mod mod; |
---|
74 | 74 | struct rsnd_kctrl_cfg_m pass; |
---|
75 | | - struct rsnd_kctrl_cfg_m sv0; |
---|
76 | | - struct rsnd_kctrl_cfg_m sv1; |
---|
77 | | - struct rsnd_kctrl_cfg_m sv2; |
---|
78 | | - struct rsnd_kctrl_cfg_m sv3; |
---|
| 75 | + struct rsnd_kctrl_cfg_m sv[4]; |
---|
79 | 76 | struct rsnd_kctrl_cfg_s reset; |
---|
80 | 77 | int channels; |
---|
81 | 78 | u32 flags; |
---|
.. | .. |
---|
107 | 104 | rsnd_mod_write(mod, CTU_SWRSR, 0); |
---|
108 | 105 | } |
---|
109 | 106 | |
---|
110 | | -int rsnd_ctu_converted_channel(struct rsnd_mod *mod) |
---|
111 | | -{ |
---|
112 | | - struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod); |
---|
113 | | - |
---|
114 | | - return ctu->channels; |
---|
115 | | -} |
---|
116 | | - |
---|
117 | 107 | static int rsnd_ctu_probe_(struct rsnd_mod *mod, |
---|
118 | 108 | struct rsnd_dai_stream *io, |
---|
119 | 109 | struct rsnd_priv *priv) |
---|
120 | 110 | { |
---|
121 | | - return rsnd_cmd_attach(io, rsnd_mod_id(mod) / 4); |
---|
| 111 | + return rsnd_cmd_attach(io, rsnd_mod_id(mod)); |
---|
122 | 112 | } |
---|
123 | 113 | |
---|
124 | 114 | static void rsnd_ctu_value_init(struct rsnd_dai_stream *io, |
---|
.. | .. |
---|
127 | 117 | struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod); |
---|
128 | 118 | u32 cpmdr = 0; |
---|
129 | 119 | u32 scmdr = 0; |
---|
130 | | - int i; |
---|
| 120 | + int i, j; |
---|
131 | 121 | |
---|
132 | 122 | for (i = 0; i < RSND_MAX_CHANNELS; i++) { |
---|
133 | 123 | u32 val = rsnd_kctrl_valm(ctu->pass, i); |
---|
.. | .. |
---|
146 | 136 | |
---|
147 | 137 | rsnd_mod_write(mod, CTU_SCMDR, scmdr); |
---|
148 | 138 | |
---|
149 | | - if (scmdr > 0) { |
---|
150 | | - rsnd_mod_write(mod, CTU_SV00R, rsnd_kctrl_valm(ctu->sv0, 0)); |
---|
151 | | - rsnd_mod_write(mod, CTU_SV01R, rsnd_kctrl_valm(ctu->sv0, 1)); |
---|
152 | | - rsnd_mod_write(mod, CTU_SV02R, rsnd_kctrl_valm(ctu->sv0, 2)); |
---|
153 | | - rsnd_mod_write(mod, CTU_SV03R, rsnd_kctrl_valm(ctu->sv0, 3)); |
---|
154 | | - rsnd_mod_write(mod, CTU_SV04R, rsnd_kctrl_valm(ctu->sv0, 4)); |
---|
155 | | - rsnd_mod_write(mod, CTU_SV05R, rsnd_kctrl_valm(ctu->sv0, 5)); |
---|
156 | | - rsnd_mod_write(mod, CTU_SV06R, rsnd_kctrl_valm(ctu->sv0, 6)); |
---|
157 | | - rsnd_mod_write(mod, CTU_SV07R, rsnd_kctrl_valm(ctu->sv0, 7)); |
---|
158 | | - } |
---|
159 | | - if (scmdr > 1) { |
---|
160 | | - rsnd_mod_write(mod, CTU_SV10R, rsnd_kctrl_valm(ctu->sv1, 0)); |
---|
161 | | - rsnd_mod_write(mod, CTU_SV11R, rsnd_kctrl_valm(ctu->sv1, 1)); |
---|
162 | | - rsnd_mod_write(mod, CTU_SV12R, rsnd_kctrl_valm(ctu->sv1, 2)); |
---|
163 | | - rsnd_mod_write(mod, CTU_SV13R, rsnd_kctrl_valm(ctu->sv1, 3)); |
---|
164 | | - rsnd_mod_write(mod, CTU_SV14R, rsnd_kctrl_valm(ctu->sv1, 4)); |
---|
165 | | - rsnd_mod_write(mod, CTU_SV15R, rsnd_kctrl_valm(ctu->sv1, 5)); |
---|
166 | | - rsnd_mod_write(mod, CTU_SV16R, rsnd_kctrl_valm(ctu->sv1, 6)); |
---|
167 | | - rsnd_mod_write(mod, CTU_SV17R, rsnd_kctrl_valm(ctu->sv1, 7)); |
---|
168 | | - } |
---|
169 | | - if (scmdr > 2) { |
---|
170 | | - rsnd_mod_write(mod, CTU_SV20R, rsnd_kctrl_valm(ctu->sv2, 0)); |
---|
171 | | - rsnd_mod_write(mod, CTU_SV21R, rsnd_kctrl_valm(ctu->sv2, 1)); |
---|
172 | | - rsnd_mod_write(mod, CTU_SV22R, rsnd_kctrl_valm(ctu->sv2, 2)); |
---|
173 | | - rsnd_mod_write(mod, CTU_SV23R, rsnd_kctrl_valm(ctu->sv2, 3)); |
---|
174 | | - rsnd_mod_write(mod, CTU_SV24R, rsnd_kctrl_valm(ctu->sv2, 4)); |
---|
175 | | - rsnd_mod_write(mod, CTU_SV25R, rsnd_kctrl_valm(ctu->sv2, 5)); |
---|
176 | | - rsnd_mod_write(mod, CTU_SV26R, rsnd_kctrl_valm(ctu->sv2, 6)); |
---|
177 | | - rsnd_mod_write(mod, CTU_SV27R, rsnd_kctrl_valm(ctu->sv2, 7)); |
---|
178 | | - } |
---|
179 | | - if (scmdr > 3) { |
---|
180 | | - rsnd_mod_write(mod, CTU_SV30R, rsnd_kctrl_valm(ctu->sv3, 0)); |
---|
181 | | - rsnd_mod_write(mod, CTU_SV31R, rsnd_kctrl_valm(ctu->sv3, 1)); |
---|
182 | | - rsnd_mod_write(mod, CTU_SV32R, rsnd_kctrl_valm(ctu->sv3, 2)); |
---|
183 | | - rsnd_mod_write(mod, CTU_SV33R, rsnd_kctrl_valm(ctu->sv3, 3)); |
---|
184 | | - rsnd_mod_write(mod, CTU_SV34R, rsnd_kctrl_valm(ctu->sv3, 4)); |
---|
185 | | - rsnd_mod_write(mod, CTU_SV35R, rsnd_kctrl_valm(ctu->sv3, 5)); |
---|
186 | | - rsnd_mod_write(mod, CTU_SV36R, rsnd_kctrl_valm(ctu->sv3, 6)); |
---|
187 | | - rsnd_mod_write(mod, CTU_SV37R, rsnd_kctrl_valm(ctu->sv3, 7)); |
---|
| 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)); |
---|
188 | 146 | } |
---|
189 | 147 | |
---|
190 | 148 | rsnd_mod_write(mod, CTU_CTUIR, 0); |
---|
.. | .. |
---|
201 | 159 | |
---|
202 | 160 | for (i = 0; i < RSND_MAX_CHANNELS; i++) { |
---|
203 | 161 | rsnd_kctrl_valm(ctu->pass, i) = 0; |
---|
204 | | - rsnd_kctrl_valm(ctu->sv0, i) = 0; |
---|
205 | | - rsnd_kctrl_valm(ctu->sv1, i) = 0; |
---|
206 | | - rsnd_kctrl_valm(ctu->sv2, i) = 0; |
---|
207 | | - rsnd_kctrl_valm(ctu->sv3, 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; |
---|
208 | 166 | } |
---|
209 | 167 | rsnd_kctrl_vals(ctu->reset) = 0; |
---|
210 | 168 | } |
---|
.. | .. |
---|
213 | 171 | struct rsnd_dai_stream *io, |
---|
214 | 172 | struct rsnd_priv *priv) |
---|
215 | 173 | { |
---|
216 | | - rsnd_mod_power_on(mod); |
---|
| 174 | + int ret; |
---|
| 175 | + |
---|
| 176 | + ret = rsnd_mod_power_on(mod); |
---|
| 177 | + if (ret < 0) |
---|
| 178 | + return ret; |
---|
217 | 179 | |
---|
218 | 180 | rsnd_ctu_activation(mod); |
---|
219 | 181 | |
---|
.. | .. |
---|
229 | 191 | rsnd_ctu_halt(mod); |
---|
230 | 192 | |
---|
231 | 193 | rsnd_mod_power_off(mod); |
---|
232 | | - |
---|
233 | | - return 0; |
---|
234 | | -} |
---|
235 | | - |
---|
236 | | -static int rsnd_ctu_hw_params(struct rsnd_mod *mod, |
---|
237 | | - struct rsnd_dai_stream *io, |
---|
238 | | - struct snd_pcm_substream *substream, |
---|
239 | | - struct snd_pcm_hw_params *fe_params) |
---|
240 | | -{ |
---|
241 | | - struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod); |
---|
242 | | - struct snd_soc_pcm_runtime *fe = substream->private_data; |
---|
243 | | - |
---|
244 | | - /* |
---|
245 | | - * CTU assumes that it is used under DPCM if user want to use |
---|
246 | | - * channel transfer. Then, CTU should be FE. |
---|
247 | | - * And then, this function will be called *after* BE settings. |
---|
248 | | - * this means, each BE already has fixuped hw_params. |
---|
249 | | - * see |
---|
250 | | - * dpcm_fe_dai_hw_params() |
---|
251 | | - * dpcm_be_dai_hw_params() |
---|
252 | | - */ |
---|
253 | | - ctu->channels = 0; |
---|
254 | | - if (fe->dai_link->dynamic) { |
---|
255 | | - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
---|
256 | | - struct device *dev = rsnd_priv_to_dev(priv); |
---|
257 | | - struct snd_soc_dpcm *dpcm; |
---|
258 | | - struct snd_pcm_hw_params *be_params; |
---|
259 | | - int stream = substream->stream; |
---|
260 | | - |
---|
261 | | - list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { |
---|
262 | | - be_params = &dpcm->hw_params; |
---|
263 | | - if (params_channels(fe_params) != params_channels(be_params)) |
---|
264 | | - ctu->channels = params_channels(be_params); |
---|
265 | | - } |
---|
266 | | - |
---|
267 | | - dev_dbg(dev, "CTU convert channels %d\n", ctu->channels); |
---|
268 | | - } |
---|
269 | 194 | |
---|
270 | 195 | return 0; |
---|
271 | 196 | } |
---|
.. | .. |
---|
291 | 216 | ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV0", |
---|
292 | 217 | rsnd_kctrl_accept_anytime, |
---|
293 | 218 | NULL, |
---|
294 | | - &ctu->sv0, RSND_MAX_CHANNELS, |
---|
| 219 | + &ctu->sv[0], RSND_MAX_CHANNELS, |
---|
295 | 220 | 0x00FFFFFF); |
---|
296 | 221 | if (ret < 0) |
---|
297 | 222 | return ret; |
---|
.. | .. |
---|
300 | 225 | ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV1", |
---|
301 | 226 | rsnd_kctrl_accept_anytime, |
---|
302 | 227 | NULL, |
---|
303 | | - &ctu->sv1, RSND_MAX_CHANNELS, |
---|
| 228 | + &ctu->sv[1], RSND_MAX_CHANNELS, |
---|
304 | 229 | 0x00FFFFFF); |
---|
305 | 230 | if (ret < 0) |
---|
306 | 231 | return ret; |
---|
.. | .. |
---|
309 | 234 | ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV2", |
---|
310 | 235 | rsnd_kctrl_accept_anytime, |
---|
311 | 236 | NULL, |
---|
312 | | - &ctu->sv2, RSND_MAX_CHANNELS, |
---|
| 237 | + &ctu->sv[2], RSND_MAX_CHANNELS, |
---|
313 | 238 | 0x00FFFFFF); |
---|
314 | 239 | if (ret < 0) |
---|
315 | 240 | return ret; |
---|
.. | .. |
---|
318 | 243 | ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV3", |
---|
319 | 244 | rsnd_kctrl_accept_anytime, |
---|
320 | 245 | NULL, |
---|
321 | | - &ctu->sv3, RSND_MAX_CHANNELS, |
---|
| 246 | + &ctu->sv[3], RSND_MAX_CHANNELS, |
---|
322 | 247 | 0x00FFFFFF); |
---|
323 | 248 | if (ret < 0) |
---|
324 | 249 | return ret; |
---|
.. | .. |
---|
334 | 259 | return ret; |
---|
335 | 260 | } |
---|
336 | 261 | |
---|
| 262 | +static int rsnd_ctu_id(struct rsnd_mod *mod) |
---|
| 263 | +{ |
---|
| 264 | + /* |
---|
| 265 | + * ctu00: -> 0, ctu01: -> 0, ctu02: -> 0, ctu03: -> 0 |
---|
| 266 | + * ctu10: -> 1, ctu11: -> 1, ctu12: -> 1, ctu13: -> 1 |
---|
| 267 | + */ |
---|
| 268 | + return mod->id / 4; |
---|
| 269 | +} |
---|
| 270 | + |
---|
| 271 | +static int rsnd_ctu_id_sub(struct rsnd_mod *mod) |
---|
| 272 | +{ |
---|
| 273 | + /* |
---|
| 274 | + * ctu00: -> 0, ctu01: -> 1, ctu02: -> 2, ctu03: -> 3 |
---|
| 275 | + * ctu10: -> 0, ctu11: -> 1, ctu12: -> 2, ctu13: -> 3 |
---|
| 276 | + */ |
---|
| 277 | + return mod->id % 4; |
---|
| 278 | +} |
---|
| 279 | + |
---|
337 | 280 | static struct rsnd_mod_ops rsnd_ctu_ops = { |
---|
338 | 281 | .name = CTU_NAME, |
---|
339 | 282 | .probe = rsnd_ctu_probe_, |
---|
340 | 283 | .init = rsnd_ctu_init, |
---|
341 | 284 | .quit = rsnd_ctu_quit, |
---|
342 | | - .hw_params = rsnd_ctu_hw_params, |
---|
343 | 285 | .pcm_new = rsnd_ctu_pcm_new, |
---|
| 286 | + .get_status = rsnd_mod_get_status, |
---|
| 287 | + .id = rsnd_ctu_id, |
---|
| 288 | + .id_sub = rsnd_ctu_id_sub, |
---|
| 289 | + .id_cmd = rsnd_mod_id_raw, |
---|
344 | 290 | }; |
---|
345 | 291 | |
---|
346 | 292 | struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) |
---|
.. | .. |
---|
404 | 350 | } |
---|
405 | 351 | |
---|
406 | 352 | ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, |
---|
407 | | - clk, rsnd_mod_get_status, RSND_MOD_CTU, i); |
---|
| 353 | + clk, RSND_MOD_CTU, i); |
---|
408 | 354 | if (ret) { |
---|
409 | 355 | of_node_put(np); |
---|
410 | 356 | goto rsnd_ctu_probe_done; |
---|