| .. | .. |
|---|
| 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; |
|---|