blob: a1d9f84d967423473063386634904ee8adb73a43 [file] [log] [blame]
Jeeja KPe4e2d2f2015-10-07 11:31:52 +01001/*
2 * skl-topology.c - Implements Platform component ALSA controls/widget
3 * handlers.
4 *
5 * Copyright (C) 2014-2015 Intel Corp
6 * Author: Jeeja KP <jeeja.kp@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#include <linux/slab.h>
20#include <linux/types.h>
21#include <linux/firmware.h>
22#include <sound/soc.h>
23#include <sound/soc-topology.h>
24#include "skl-sst-dsp.h"
25#include "skl-sst-ipc.h"
26#include "skl-topology.h"
27#include "skl.h"
28#include "skl-tplg-interface.h"
Dharageswari R6c5768b2015-12-03 23:29:50 +053029#include "../common/sst-dsp.h"
30#include "../common/sst-dsp-priv.h"
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010031
Jeeja KPf7590d42015-10-07 11:31:53 +010032#define SKL_CH_FIXUP_MASK (1 << 0)
33#define SKL_RATE_FIXUP_MASK (1 << 1)
34#define SKL_FMT_FIXUP_MASK (1 << 2)
35
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010036/*
37 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
38 * ignore. This helpers checks if the SKL driver handles this widget type
39 */
40static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
41{
42 switch (w->id) {
43 case snd_soc_dapm_dai_link:
44 case snd_soc_dapm_dai_in:
45 case snd_soc_dapm_aif_in:
46 case snd_soc_dapm_aif_out:
47 case snd_soc_dapm_dai_out:
48 case snd_soc_dapm_switch:
49 return false;
50 default:
51 return true;
52 }
53}
54
55/*
56 * Each pipelines needs memory to be allocated. Check if we have free memory
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053057 * from available pool.
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010058 */
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053059static bool skl_is_pipe_mem_avail(struct skl *skl,
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010060 struct skl_module_cfg *mconfig)
61{
62 struct skl_sst *ctx = skl->skl_sst;
63
64 if (skl->resource.mem + mconfig->pipe->memory_pages >
65 skl->resource.max_mem) {
66 dev_err(ctx->dev,
67 "%s: module_id %d instance %d\n", __func__,
68 mconfig->id.module_id,
69 mconfig->id.instance_id);
70 dev_err(ctx->dev,
71 "exceeds ppl memory available %d mem %d\n",
72 skl->resource.max_mem, skl->resource.mem);
73 return false;
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053074 } else {
75 return true;
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010076 }
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053077}
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010078
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053079/*
80 * Add the mem to the mem pool. This is freed when pipe is deleted.
81 * Note: DSP does actual memory management we only keep track for complete
82 * pool
83 */
84static void skl_tplg_alloc_pipe_mem(struct skl *skl,
85 struct skl_module_cfg *mconfig)
86{
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010087 skl->resource.mem += mconfig->pipe->memory_pages;
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010088}
89
90/*
91 * Pipeline needs needs DSP CPU resources for computation, this is
92 * quantified in MCPS (Million Clocks Per Second) required for module/pipe
93 *
94 * Each pipelines needs mcps to be allocated. Check if we have mcps for this
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053095 * pipe.
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010096 */
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +053097
98static bool skl_is_pipe_mcps_avail(struct skl *skl,
Jeeja KPe4e2d2f2015-10-07 11:31:52 +010099 struct skl_module_cfg *mconfig)
100{
101 struct skl_sst *ctx = skl->skl_sst;
102
103 if (skl->resource.mcps + mconfig->mcps > skl->resource.max_mcps) {
104 dev_err(ctx->dev,
105 "%s: module_id %d instance %d\n", __func__,
106 mconfig->id.module_id, mconfig->id.instance_id);
107 dev_err(ctx->dev,
Guneshwor Singh7ca42f52016-02-03 17:59:46 +0530108 "exceeds ppl mcps available %d > mem %d\n",
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100109 skl->resource.max_mcps, skl->resource.mcps);
110 return false;
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530111 } else {
112 return true;
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100113 }
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530114}
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100115
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530116static void skl_tplg_alloc_pipe_mcps(struct skl *skl,
117 struct skl_module_cfg *mconfig)
118{
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100119 skl->resource.mcps += mconfig->mcps;
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100120}
121
122/*
123 * Free the mcps when tearing down
124 */
125static void
126skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
127{
128 skl->resource.mcps -= mconfig->mcps;
129}
130
131/*
132 * Free the memory when tearing down
133 */
134static void
135skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig)
136{
137 skl->resource.mem -= mconfig->pipe->memory_pages;
138}
139
Jeeja KPf7590d42015-10-07 11:31:53 +0100140
141static void skl_dump_mconfig(struct skl_sst *ctx,
142 struct skl_module_cfg *mcfg)
143{
144 dev_dbg(ctx->dev, "Dumping config\n");
145 dev_dbg(ctx->dev, "Input Format:\n");
Hardik T Shah4cd98992015-10-27 09:22:55 +0900146 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels);
147 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq);
148 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg);
149 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth);
Jeeja KPf7590d42015-10-07 11:31:53 +0100150 dev_dbg(ctx->dev, "Output Format:\n");
Hardik T Shah4cd98992015-10-27 09:22:55 +0900151 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels);
152 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq);
153 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth);
154 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg);
Jeeja KPf7590d42015-10-07 11:31:53 +0100155}
156
Subhransu S. Prustyea5a1372016-04-14 10:07:36 +0530157static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs)
158{
159 int slot_map = 0xFFFFFFFF;
160 int start_slot = 0;
161 int i;
162
163 for (i = 0; i < chs; i++) {
164 /*
165 * For 2 channels with starting slot as 0, slot map will
166 * look like 0xFFFFFF10.
167 */
168 slot_map &= (~(0xF << (4 * i)) | (start_slot << (4 * i)));
169 start_slot++;
170 }
171 fmt->ch_map = slot_map;
172}
173
Jeeja KPf7590d42015-10-07 11:31:53 +0100174static void skl_tplg_update_params(struct skl_module_fmt *fmt,
175 struct skl_pipe_params *params, int fixup)
176{
177 if (fixup & SKL_RATE_FIXUP_MASK)
178 fmt->s_freq = params->s_freq;
Subhransu S. Prustyea5a1372016-04-14 10:07:36 +0530179 if (fixup & SKL_CH_FIXUP_MASK) {
Jeeja KPf7590d42015-10-07 11:31:53 +0100180 fmt->channels = params->ch;
Subhransu S. Prustyea5a1372016-04-14 10:07:36 +0530181 skl_tplg_update_chmap(fmt, fmt->channels);
182 }
Jeeja KP98256f82015-11-23 22:26:25 +0530183 if (fixup & SKL_FMT_FIXUP_MASK) {
184 fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
185
186 /*
187 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
188 * container so update bit depth accordingly
189 */
190 switch (fmt->valid_bit_depth) {
191 case SKL_DEPTH_16BIT:
192 fmt->bit_depth = fmt->valid_bit_depth;
193 break;
194
195 default:
196 fmt->bit_depth = SKL_DEPTH_32BIT;
197 break;
198 }
199 }
200
Jeeja KPf7590d42015-10-07 11:31:53 +0100201}
202
203/*
204 * A pipeline may have modules which impact the pcm parameters, like SRC,
205 * channel converter, format converter.
206 * We need to calculate the output params by applying the 'fixup'
207 * Topology will tell driver which type of fixup is to be applied by
208 * supplying the fixup mask, so based on that we calculate the output
209 *
210 * Now In FE the pcm hw_params is source/target format. Same is applicable
211 * for BE with its hw_params invoked.
212 * here based on FE, BE pipeline and direction we calculate the input and
213 * outfix and then apply that for a module
214 */
215static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
216 struct skl_pipe_params *params, bool is_fe)
217{
218 int in_fixup, out_fixup;
219 struct skl_module_fmt *in_fmt, *out_fmt;
220
Hardik T Shah4cd98992015-10-27 09:22:55 +0900221 /* Fixups will be applied to pin 0 only */
222 in_fmt = &m_cfg->in_fmt[0];
223 out_fmt = &m_cfg->out_fmt[0];
Jeeja KPf7590d42015-10-07 11:31:53 +0100224
225 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
226 if (is_fe) {
227 in_fixup = m_cfg->params_fixup;
228 out_fixup = (~m_cfg->converter) &
229 m_cfg->params_fixup;
230 } else {
231 out_fixup = m_cfg->params_fixup;
232 in_fixup = (~m_cfg->converter) &
233 m_cfg->params_fixup;
234 }
235 } else {
236 if (is_fe) {
237 out_fixup = m_cfg->params_fixup;
238 in_fixup = (~m_cfg->converter) &
239 m_cfg->params_fixup;
240 } else {
241 in_fixup = m_cfg->params_fixup;
242 out_fixup = (~m_cfg->converter) &
243 m_cfg->params_fixup;
244 }
245 }
246
247 skl_tplg_update_params(in_fmt, params, in_fixup);
248 skl_tplg_update_params(out_fmt, params, out_fixup);
249}
250
251/*
252 * A module needs input and output buffers, which are dependent upon pcm
253 * params, so once we have calculate params, we need buffer calculation as
254 * well.
255 */
256static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
257 struct skl_module_cfg *mcfg)
258{
259 int multiplier = 1;
Hardik T Shah4cd98992015-10-27 09:22:55 +0900260 struct skl_module_fmt *in_fmt, *out_fmt;
Subhransu S. Prustyf0c8e1d2016-04-12 10:31:23 +0530261 int in_rate, out_rate;
Hardik T Shah4cd98992015-10-27 09:22:55 +0900262
263
264 /* Since fixups is applied to pin 0 only, ibs, obs needs
265 * change for pin 0 only
266 */
267 in_fmt = &mcfg->in_fmt[0];
268 out_fmt = &mcfg->out_fmt[0];
Jeeja KPf7590d42015-10-07 11:31:53 +0100269
270 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
271 multiplier = 5;
Jeeja KPf7590d42015-10-07 11:31:53 +0100272
Subhransu S. Prustyf0c8e1d2016-04-12 10:31:23 +0530273 if (in_fmt->s_freq % 1000)
274 in_rate = (in_fmt->s_freq / 1000) + 1;
275 else
276 in_rate = (in_fmt->s_freq / 1000);
277
278 mcfg->ibs = in_rate * (mcfg->in_fmt->channels) *
279 (mcfg->in_fmt->bit_depth >> 3) *
280 multiplier;
281
282 if (mcfg->out_fmt->s_freq % 1000)
283 out_rate = (mcfg->out_fmt->s_freq / 1000) + 1;
284 else
285 out_rate = (mcfg->out_fmt->s_freq / 1000);
286
287 mcfg->obs = out_rate * (mcfg->out_fmt->channels) *
288 (mcfg->out_fmt->bit_depth >> 3) *
289 multiplier;
Jeeja KPf7590d42015-10-07 11:31:53 +0100290}
291
Jeeja KP2d1419a2016-02-05 12:19:10 +0530292static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
293 struct skl_sst *ctx)
294{
295 struct skl_module_cfg *m_cfg = w->priv;
296 int link_type, dir;
297 u32 ch, s_freq, s_fmt;
298 struct nhlt_specific_cfg *cfg;
299 struct skl *skl = get_skl_ctx(ctx->dev);
300
301 /* check if we already have blob */
302 if (m_cfg->formats_config.caps_size > 0)
303 return 0;
304
Jeeja KPc7c6c732016-03-01 07:59:10 +0530305 dev_dbg(ctx->dev, "Applying default cfg blob\n");
Jeeja KP2d1419a2016-02-05 12:19:10 +0530306 switch (m_cfg->dev_type) {
307 case SKL_DEVICE_DMIC:
308 link_type = NHLT_LINK_DMIC;
Jeeja KPc7c6c732016-03-01 07:59:10 +0530309 dir = SNDRV_PCM_STREAM_CAPTURE;
Jeeja KP2d1419a2016-02-05 12:19:10 +0530310 s_freq = m_cfg->in_fmt[0].s_freq;
311 s_fmt = m_cfg->in_fmt[0].bit_depth;
312 ch = m_cfg->in_fmt[0].channels;
313 break;
314
315 case SKL_DEVICE_I2S:
316 link_type = NHLT_LINK_SSP;
317 if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) {
Jeeja KPc7c6c732016-03-01 07:59:10 +0530318 dir = SNDRV_PCM_STREAM_PLAYBACK;
Jeeja KP2d1419a2016-02-05 12:19:10 +0530319 s_freq = m_cfg->out_fmt[0].s_freq;
320 s_fmt = m_cfg->out_fmt[0].bit_depth;
321 ch = m_cfg->out_fmt[0].channels;
Jeeja KPc7c6c732016-03-01 07:59:10 +0530322 } else {
323 dir = SNDRV_PCM_STREAM_CAPTURE;
324 s_freq = m_cfg->in_fmt[0].s_freq;
325 s_fmt = m_cfg->in_fmt[0].bit_depth;
326 ch = m_cfg->in_fmt[0].channels;
Jeeja KP2d1419a2016-02-05 12:19:10 +0530327 }
328 break;
329
330 default:
331 return -EINVAL;
332 }
333
334 /* update the blob based on virtual bus_id and default params */
335 cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type,
336 s_fmt, ch, s_freq, dir);
337 if (cfg) {
338 m_cfg->formats_config.caps_size = cfg->size;
339 m_cfg->formats_config.caps = (u32 *) &cfg->caps;
340 } else {
341 dev_err(ctx->dev, "Blob NULL for id %x type %d dirn %d\n",
342 m_cfg->vbus_id, link_type, dir);
343 dev_err(ctx->dev, "PCM: ch %d, freq %d, fmt %d\n",
344 ch, s_freq, s_fmt);
345 return -EIO;
346 }
347
348 return 0;
349}
350
Jeeja KPf7590d42015-10-07 11:31:53 +0100351static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
352 struct skl_sst *ctx)
353{
354 struct skl_module_cfg *m_cfg = w->priv;
355 struct skl_pipe_params *params = m_cfg->pipe->p_params;
356 int p_conn_type = m_cfg->pipe->conn_type;
357 bool is_fe;
358
359 if (!m_cfg->params_fixup)
360 return;
361
362 dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n",
363 w->name);
364
365 skl_dump_mconfig(ctx, m_cfg);
366
367 if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
368 is_fe = true;
369 else
370 is_fe = false;
371
372 skl_tplg_update_params_fixup(m_cfg, params, is_fe);
373 skl_tplg_update_buffer_size(ctx, m_cfg);
374
375 dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n",
376 w->name);
377
378 skl_dump_mconfig(ctx, m_cfg);
379}
380
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100381/*
Jeeja KPabb74002015-11-28 15:01:49 +0530382 * some modules can have multiple params set from user control and
383 * need to be set after module is initialized. If set_param flag is
384 * set module params will be done after module is initialised.
385 */
386static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
387 struct skl_sst *ctx)
388{
389 int i, ret;
390 struct skl_module_cfg *mconfig = w->priv;
391 const struct snd_kcontrol_new *k;
392 struct soc_bytes_ext *sb;
393 struct skl_algo_data *bc;
394 struct skl_specific_cfg *sp_cfg;
395
396 if (mconfig->formats_config.caps_size > 0 &&
Jeeja KP4ced1822015-12-03 23:29:53 +0530397 mconfig->formats_config.set_params == SKL_PARAM_SET) {
Jeeja KPabb74002015-11-28 15:01:49 +0530398 sp_cfg = &mconfig->formats_config;
399 ret = skl_set_module_params(ctx, sp_cfg->caps,
400 sp_cfg->caps_size,
401 sp_cfg->param_id, mconfig);
402 if (ret < 0)
403 return ret;
404 }
405
406 for (i = 0; i < w->num_kcontrols; i++) {
407 k = &w->kcontrol_news[i];
408 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
409 sb = (void *) k->private_value;
410 bc = (struct skl_algo_data *)sb->dobj.private;
411
Jeeja KP4ced1822015-12-03 23:29:53 +0530412 if (bc->set_params == SKL_PARAM_SET) {
Jeeja KPabb74002015-11-28 15:01:49 +0530413 ret = skl_set_module_params(ctx,
Dharageswari R0d682102016-07-08 18:15:03 +0530414 (u32 *)bc->params, bc->size,
Jeeja KPabb74002015-11-28 15:01:49 +0530415 bc->param_id, mconfig);
416 if (ret < 0)
417 return ret;
418 }
419 }
420 }
421
422 return 0;
423}
424
425/*
426 * some module param can set from user control and this is required as
427 * when module is initailzed. if module param is required in init it is
428 * identifed by set_param flag. if set_param flag is not set, then this
429 * parameter needs to set as part of module init.
430 */
431static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
432{
433 const struct snd_kcontrol_new *k;
434 struct soc_bytes_ext *sb;
435 struct skl_algo_data *bc;
436 struct skl_module_cfg *mconfig = w->priv;
437 int i;
438
439 for (i = 0; i < w->num_kcontrols; i++) {
440 k = &w->kcontrol_news[i];
441 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
442 sb = (struct soc_bytes_ext *)k->private_value;
443 bc = (struct skl_algo_data *)sb->dobj.private;
444
Jeeja KP4ced1822015-12-03 23:29:53 +0530445 if (bc->set_params != SKL_PARAM_INIT)
Jeeja KPabb74002015-11-28 15:01:49 +0530446 continue;
447
448 mconfig->formats_config.caps = (u32 *)&bc->params;
Dharageswari R0d682102016-07-08 18:15:03 +0530449 mconfig->formats_config.caps_size = bc->size;
Jeeja KPabb74002015-11-28 15:01:49 +0530450
451 break;
452 }
453 }
454
455 return 0;
456}
457
458/*
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100459 * Inside a pipe instance, we can have various modules. These modules need
460 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
461 * skl_init_module() routine, so invoke that for all modules in a pipeline
462 */
463static int
464skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
465{
466 struct skl_pipe_module *w_module;
467 struct snd_soc_dapm_widget *w;
468 struct skl_module_cfg *mconfig;
469 struct skl_sst *ctx = skl->skl_sst;
470 int ret = 0;
471
472 list_for_each_entry(w_module, &pipe->w_list, node) {
473 w = w_module->w;
474 mconfig = w->priv;
475
Vinod Koulb7c50552016-07-26 18:06:40 +0530476 /* check if module ids are populated */
477 if (mconfig->id.module_id < 0) {
478 struct skl_dfw_module *dfw_config;
479
480 dfw_config = kzalloc(sizeof(dfw_config), GFP_KERNEL);
481 if (!dfw_config)
482 return -ENOMEM;
483
484 ret = snd_skl_get_module_info(skl->skl_sst,
485 mconfig->guid, dfw_config);
486 if (ret < 0) {
487 dev_err(skl->skl_sst->dev,
488 "query module info failed: %d\n", ret);
489 kfree(dfw_config);
490 return ret;
491 }
492 mconfig->id.module_id = dfw_config->module_id;
493 mconfig->is_loadable = dfw_config->is_loadable;
494
495 kfree(dfw_config);
496 }
497
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100498 /* check resource available */
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530499 if (!skl_is_pipe_mcps_avail(skl, mconfig))
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100500 return -ENOMEM;
501
Dharageswari R6c5768b2015-12-03 23:29:50 +0530502 if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
503 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
504 mconfig->id.module_id, mconfig->guid);
505 if (ret < 0)
506 return ret;
Jeeja KPd6436782016-03-28 22:11:30 +0530507
508 mconfig->m_state = SKL_MODULE_LOADED;
Dharageswari R6c5768b2015-12-03 23:29:50 +0530509 }
510
Jeeja KP2d1419a2016-02-05 12:19:10 +0530511 /* update blob if blob is null for be with default value */
512 skl_tplg_update_be_blob(w, ctx);
513
Jeeja KPf7590d42015-10-07 11:31:53 +0100514 /*
515 * apply fix/conversion to module params based on
516 * FE/BE params
517 */
518 skl_tplg_update_module_params(w, ctx);
Jeeja KPabb74002015-11-28 15:01:49 +0530519
520 skl_tplg_set_module_init_data(w);
Jeeja KP9939a9c2015-11-28 15:01:47 +0530521 ret = skl_init_module(ctx, mconfig);
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100522 if (ret < 0)
523 return ret;
Jeeja KPabb74002015-11-28 15:01:49 +0530524
Dharageswari R260eb732016-06-03 18:29:38 +0530525 skl_tplg_alloc_pipe_mcps(skl, mconfig);
Jeeja KPabb74002015-11-28 15:01:49 +0530526 ret = skl_tplg_set_module_params(w, ctx);
Jeeja KPe4e2d2f2015-10-07 11:31:52 +0100527 if (ret < 0)
528 return ret;
529 }
530
531 return 0;
532}
Vinod Kould93f8e52015-10-07 11:31:54 +0100533
Dharageswari R6c5768b2015-12-03 23:29:50 +0530534static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
535 struct skl_pipe *pipe)
536{
537 struct skl_pipe_module *w_module = NULL;
538 struct skl_module_cfg *mconfig = NULL;
539
540 list_for_each_entry(w_module, &pipe->w_list, node) {
541 mconfig = w_module->w->priv;
542
Jeeja KPd6436782016-03-28 22:11:30 +0530543 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
544 mconfig->m_state > SKL_MODULE_UNINIT)
Dharageswari R6c5768b2015-12-03 23:29:50 +0530545 return ctx->dsp->fw_ops.unload_mod(ctx->dsp,
546 mconfig->id.module_id);
547 }
548
549 /* no modules to unload in this path, so return */
550 return 0;
551}
552
Vinod Kould93f8e52015-10-07 11:31:54 +0100553/*
554 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
555 * need create the pipeline. So we do following:
556 * - check the resources
557 * - Create the pipeline
558 * - Initialize the modules in pipeline
559 * - finally bind all modules together
560 */
561static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
562 struct skl *skl)
563{
564 int ret;
565 struct skl_module_cfg *mconfig = w->priv;
566 struct skl_pipe_module *w_module;
567 struct skl_pipe *s_pipe = mconfig->pipe;
568 struct skl_module_cfg *src_module = NULL, *dst_module;
569 struct skl_sst *ctx = skl->skl_sst;
570
571 /* check resource available */
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530572 if (!skl_is_pipe_mcps_avail(skl, mconfig))
Vinod Kould93f8e52015-10-07 11:31:54 +0100573 return -EBUSY;
574
Dharageswari.R9ba8ffe2016-02-03 17:59:47 +0530575 if (!skl_is_pipe_mem_avail(skl, mconfig))
Vinod Kould93f8e52015-10-07 11:31:54 +0100576 return -ENOMEM;
577
578 /*
579 * Create a list of modules for pipe.
580 * This list contains modules from source to sink
581 */
582 ret = skl_create_pipeline(ctx, mconfig->pipe);
583 if (ret < 0)
584 return ret;
585
Dharageswari R260eb732016-06-03 18:29:38 +0530586 skl_tplg_alloc_pipe_mem(skl, mconfig);
587 skl_tplg_alloc_pipe_mcps(skl, mconfig);
Vinod Kould93f8e52015-10-07 11:31:54 +0100588
589 /* Init all pipe modules from source to sink */
590 ret = skl_tplg_init_pipe_modules(skl, s_pipe);
591 if (ret < 0)
592 return ret;
593
594 /* Bind modules from source to sink */
595 list_for_each_entry(w_module, &s_pipe->w_list, node) {
596 dst_module = w_module->w->priv;
597
598 if (src_module == NULL) {
599 src_module = dst_module;
600 continue;
601 }
602
603 ret = skl_bind_modules(ctx, src_module, dst_module);
604 if (ret < 0)
605 return ret;
606
607 src_module = dst_module;
608 }
609
610 return 0;
611}
612
Jeeja KPcc6a4042016-02-05 12:19:08 +0530613/*
614 * Some modules require params to be set after the module is bound to
615 * all pins connected.
616 *
617 * The module provider initializes set_param flag for such modules and we
618 * send params after binding
619 */
620static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
621 struct skl_module_cfg *mcfg, struct skl_sst *ctx)
622{
623 int i, ret;
624 struct skl_module_cfg *mconfig = w->priv;
625 const struct snd_kcontrol_new *k;
626 struct soc_bytes_ext *sb;
627 struct skl_algo_data *bc;
628 struct skl_specific_cfg *sp_cfg;
629
630 /*
631 * check all out/in pins are in bind state.
632 * if so set the module param
633 */
634 for (i = 0; i < mcfg->max_out_queue; i++) {
635 if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE)
636 return 0;
637 }
638
639 for (i = 0; i < mcfg->max_in_queue; i++) {
640 if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE)
641 return 0;
642 }
643
644 if (mconfig->formats_config.caps_size > 0 &&
645 mconfig->formats_config.set_params == SKL_PARAM_BIND) {
646 sp_cfg = &mconfig->formats_config;
647 ret = skl_set_module_params(ctx, sp_cfg->caps,
648 sp_cfg->caps_size,
649 sp_cfg->param_id, mconfig);
650 if (ret < 0)
651 return ret;
652 }
653
654 for (i = 0; i < w->num_kcontrols; i++) {
655 k = &w->kcontrol_news[i];
656 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
657 sb = (void *) k->private_value;
658 bc = (struct skl_algo_data *)sb->dobj.private;
659
660 if (bc->set_params == SKL_PARAM_BIND) {
661 ret = skl_set_module_params(ctx,
662 (u32 *)bc->params, bc->max,
663 bc->param_id, mconfig);
664 if (ret < 0)
665 return ret;
666 }
667 }
668 }
669
670 return 0;
671}
672
Jeeja KP8724ff12015-10-27 09:22:52 +0900673static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
674 struct skl *skl,
Jeeja KP6bd4cf82016-02-03 17:59:51 +0530675 struct snd_soc_dapm_widget *src_w,
Jeeja KP8724ff12015-10-27 09:22:52 +0900676 struct skl_module_cfg *src_mconfig)
Vinod Kould93f8e52015-10-07 11:31:54 +0100677{
678 struct snd_soc_dapm_path *p;
Jeeja KP0ed95d72015-11-13 19:22:11 +0530679 struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
Jeeja KP8724ff12015-10-27 09:22:52 +0900680 struct skl_module_cfg *sink_mconfig;
Vinod Kould93f8e52015-10-07 11:31:54 +0100681 struct skl_sst *ctx = skl->skl_sst;
Jeeja KP8724ff12015-10-27 09:22:52 +0900682 int ret;
Vinod Kould93f8e52015-10-07 11:31:54 +0100683
Jeeja KP8724ff12015-10-27 09:22:52 +0900684 snd_soc_dapm_widget_for_each_sink_path(w, p) {
Vinod Kould93f8e52015-10-07 11:31:54 +0100685 if (!p->connect)
686 continue;
687
688 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
689 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
690
Jeeja KP0ed95d72015-11-13 19:22:11 +0530691 next_sink = p->sink;
Jeeja KP6bd4cf82016-02-03 17:59:51 +0530692
693 if (!is_skl_dsp_widget_type(p->sink))
694 return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
695
Vinod Kould93f8e52015-10-07 11:31:54 +0100696 /*
697 * here we will check widgets in sink pipelines, so that
698 * can be any widgets type and we are only interested if
699 * they are ones used for SKL so check that first
700 */
701 if ((p->sink->priv != NULL) &&
702 is_skl_dsp_widget_type(p->sink)) {
703
704 sink = p->sink;
Vinod Kould93f8e52015-10-07 11:31:54 +0100705 sink_mconfig = sink->priv;
706
Jeeja KPcc6a4042016-02-05 12:19:08 +0530707 if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
708 sink_mconfig->m_state == SKL_MODULE_UNINIT)
709 continue;
710
Vinod Kould93f8e52015-10-07 11:31:54 +0100711 /* Bind source to sink, mixin is always source */
712 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
713 if (ret)
714 return ret;
715
Jeeja KPcc6a4042016-02-05 12:19:08 +0530716 /* set module params after bind */
717 skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx);
718 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
719
Vinod Kould93f8e52015-10-07 11:31:54 +0100720 /* Start sinks pipe first */
721 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
Jeeja KPd1730c32015-10-27 09:22:53 +0900722 if (sink_mconfig->pipe->conn_type !=
723 SKL_PIPE_CONN_TYPE_FE)
724 ret = skl_run_pipe(ctx,
725 sink_mconfig->pipe);
Vinod Kould93f8e52015-10-07 11:31:54 +0100726 if (ret)
727 return ret;
728 }
Vinod Kould93f8e52015-10-07 11:31:54 +0100729 }
730 }
731
Jeeja KP8724ff12015-10-27 09:22:52 +0900732 if (!sink)
Jeeja KP6bd4cf82016-02-03 17:59:51 +0530733 return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig);
Jeeja KP8724ff12015-10-27 09:22:52 +0900734
735 return 0;
736}
737
Vinod Kould93f8e52015-10-07 11:31:54 +0100738/*
739 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
740 * we need to do following:
741 * - Bind to sink pipeline
742 * Since the sink pipes can be running and we don't get mixer event on
743 * connect for already running mixer, we need to find the sink pipes
744 * here and bind to them. This way dynamic connect works.
745 * - Start sink pipeline, if not running
746 * - Then run current pipe
747 */
748static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
Jeeja KP8724ff12015-10-27 09:22:52 +0900749 struct skl *skl)
Vinod Kould93f8e52015-10-07 11:31:54 +0100750{
Jeeja KP8724ff12015-10-27 09:22:52 +0900751 struct skl_module_cfg *src_mconfig;
Vinod Kould93f8e52015-10-07 11:31:54 +0100752 struct skl_sst *ctx = skl->skl_sst;
753 int ret = 0;
754
Jeeja KP8724ff12015-10-27 09:22:52 +0900755 src_mconfig = w->priv;
Vinod Kould93f8e52015-10-07 11:31:54 +0100756
757 /*
758 * find which sink it is connected to, bind with the sink,
759 * if sink is not started, start sink pipe first, then start
760 * this pipe
761 */
Jeeja KP6bd4cf82016-02-03 17:59:51 +0530762 ret = skl_tplg_bind_sinks(w, skl, w, src_mconfig);
Vinod Kould93f8e52015-10-07 11:31:54 +0100763 if (ret)
764 return ret;
765
Vinod Kould93f8e52015-10-07 11:31:54 +0100766 /* Start source pipe last after starting all sinks */
Jeeja KPd1730c32015-10-27 09:22:53 +0900767 if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
768 return skl_run_pipe(ctx, src_mconfig->pipe);
Vinod Kould93f8e52015-10-07 11:31:54 +0100769
770 return 0;
771}
772
Jeeja KP8724ff12015-10-27 09:22:52 +0900773static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
774 struct snd_soc_dapm_widget *w, struct skl *skl)
775{
776 struct snd_soc_dapm_path *p;
777 struct snd_soc_dapm_widget *src_w = NULL;
778 struct skl_sst *ctx = skl->skl_sst;
779
780 snd_soc_dapm_widget_for_each_source_path(w, p) {
781 src_w = p->source;
782 if (!p->connect)
783 continue;
784
785 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
786 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
787
788 /*
789 * here we will check widgets in sink pipelines, so that can
790 * be any widgets type and we are only interested if they are
791 * ones used for SKL so check that first
792 */
793 if ((p->source->priv != NULL) &&
794 is_skl_dsp_widget_type(p->source)) {
795 return p->source;
796 }
797 }
798
799 if (src_w != NULL)
800 return skl_get_src_dsp_widget(src_w, skl);
801
802 return NULL;
803}
804
Vinod Kould93f8e52015-10-07 11:31:54 +0100805/*
806 * in the Post-PMU event of mixer we need to do following:
807 * - Check if this pipe is running
808 * - if not, then
809 * - bind this pipeline to its source pipeline
810 * if source pipe is already running, this means it is a dynamic
811 * connection and we need to bind only to that pipe
812 * - start this pipeline
813 */
814static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
815 struct skl *skl)
816{
817 int ret = 0;
Vinod Kould93f8e52015-10-07 11:31:54 +0100818 struct snd_soc_dapm_widget *source, *sink;
819 struct skl_module_cfg *src_mconfig, *sink_mconfig;
820 struct skl_sst *ctx = skl->skl_sst;
821 int src_pipe_started = 0;
822
823 sink = w;
824 sink_mconfig = sink->priv;
825
826 /*
827 * If source pipe is already started, that means source is driving
828 * one more sink before this sink got connected, Since source is
829 * started, bind this sink to source and start this pipe.
830 */
Jeeja KP8724ff12015-10-27 09:22:52 +0900831 source = skl_get_src_dsp_widget(w, skl);
832 if (source != NULL) {
833 src_mconfig = source->priv;
834 sink_mconfig = sink->priv;
835 src_pipe_started = 1;
Vinod Kould93f8e52015-10-07 11:31:54 +0100836
837 /*
Jeeja KP8724ff12015-10-27 09:22:52 +0900838 * check pipe state, then no need to bind or start the
839 * pipe
Vinod Kould93f8e52015-10-07 11:31:54 +0100840 */
Jeeja KP8724ff12015-10-27 09:22:52 +0900841 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
842 src_pipe_started = 0;
Vinod Kould93f8e52015-10-07 11:31:54 +0100843 }
844
845 if (src_pipe_started) {
846 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
847 if (ret)
848 return ret;
849
Jeeja KPcc6a4042016-02-05 12:19:08 +0530850 /* set module params after bind */
851 skl_tplg_set_module_bind_params(source, src_mconfig, ctx);
852 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
853
Jeeja KPd1730c32015-10-27 09:22:53 +0900854 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
855 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
Vinod Kould93f8e52015-10-07 11:31:54 +0100856 }
857
858 return ret;
859}
860
861/*
862 * in the Pre-PMD event of mixer we need to do following:
863 * - Stop the pipe
864 * - find the source connections and remove that from dapm_path_list
865 * - unbind with source pipelines if still connected
866 */
867static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
868 struct skl *skl)
869{
Vinod Kould93f8e52015-10-07 11:31:54 +0100870 struct skl_module_cfg *src_mconfig, *sink_mconfig;
Jeeja KPce1b5552015-10-27 09:22:51 +0900871 int ret = 0, i;
Vinod Kould93f8e52015-10-07 11:31:54 +0100872 struct skl_sst *ctx = skl->skl_sst;
873
Jeeja KPce1b5552015-10-27 09:22:51 +0900874 sink_mconfig = w->priv;
Vinod Kould93f8e52015-10-07 11:31:54 +0100875
876 /* Stop the pipe */
877 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
878 if (ret)
879 return ret;
880
Jeeja KPce1b5552015-10-27 09:22:51 +0900881 for (i = 0; i < sink_mconfig->max_in_queue; i++) {
882 if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) {
883 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
884 if (!src_mconfig)
885 continue;
886 /*
887 * If path_found == 1, that means pmd for source
888 * pipe has not occurred, source is connected to
889 * some other sink. so its responsibility of sink
890 * to unbind itself from source.
891 */
892 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
893 if (ret < 0)
894 return ret;
Vinod Kould93f8e52015-10-07 11:31:54 +0100895
Jeeja KPce1b5552015-10-27 09:22:51 +0900896 ret = skl_unbind_modules(ctx,
897 src_mconfig, sink_mconfig);
Vinod Kould93f8e52015-10-07 11:31:54 +0100898 }
899 }
900
Vinod Kould93f8e52015-10-07 11:31:54 +0100901 return ret;
902}
903
904/*
905 * in the Post-PMD event of mixer we need to do following:
906 * - Free the mcps used
907 * - Free the mem used
908 * - Unbind the modules within the pipeline
909 * - Delete the pipeline (modules are not required to be explicitly
910 * deleted, pipeline delete is enough here
911 */
912static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
913 struct skl *skl)
914{
915 struct skl_module_cfg *mconfig = w->priv;
916 struct skl_pipe_module *w_module;
917 struct skl_module_cfg *src_module = NULL, *dst_module;
918 struct skl_sst *ctx = skl->skl_sst;
919 struct skl_pipe *s_pipe = mconfig->pipe;
920 int ret = 0;
921
Dharageswari R260eb732016-06-03 18:29:38 +0530922 if (s_pipe->state == SKL_PIPE_INVALID)
923 return -EINVAL;
924
Vinod Kould93f8e52015-10-07 11:31:54 +0100925 skl_tplg_free_pipe_mcps(skl, mconfig);
Vinod Koul65976872015-11-23 22:26:29 +0530926 skl_tplg_free_pipe_mem(skl, mconfig);
Vinod Kould93f8e52015-10-07 11:31:54 +0100927
928 list_for_each_entry(w_module, &s_pipe->w_list, node) {
929 dst_module = w_module->w->priv;
930
Dharageswari R260eb732016-06-03 18:29:38 +0530931 if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
932 skl_tplg_free_pipe_mcps(skl, dst_module);
Vinod Kould93f8e52015-10-07 11:31:54 +0100933 if (src_module == NULL) {
934 src_module = dst_module;
935 continue;
936 }
937
Guneshwor Singh7ca42f52016-02-03 17:59:46 +0530938 skl_unbind_modules(ctx, src_module, dst_module);
Vinod Kould93f8e52015-10-07 11:31:54 +0100939 src_module = dst_module;
940 }
941
942 ret = skl_delete_pipe(ctx, mconfig->pipe);
Vinod Kould93f8e52015-10-07 11:31:54 +0100943
Dharageswari R6c5768b2015-12-03 23:29:50 +0530944 return skl_tplg_unload_pipe_modules(ctx, s_pipe);
Vinod Kould93f8e52015-10-07 11:31:54 +0100945}
946
947/*
948 * in the Post-PMD event of PGA we need to do following:
949 * - Free the mcps used
950 * - Stop the pipeline
951 * - In source pipe is connected, unbind with source pipelines
952 */
953static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
954 struct skl *skl)
955{
Vinod Kould93f8e52015-10-07 11:31:54 +0100956 struct skl_module_cfg *src_mconfig, *sink_mconfig;
Jeeja KPce1b5552015-10-27 09:22:51 +0900957 int ret = 0, i;
Vinod Kould93f8e52015-10-07 11:31:54 +0100958 struct skl_sst *ctx = skl->skl_sst;
959
Jeeja KPce1b5552015-10-27 09:22:51 +0900960 src_mconfig = w->priv;
Vinod Kould93f8e52015-10-07 11:31:54 +0100961
Vinod Kould93f8e52015-10-07 11:31:54 +0100962 /* Stop the pipe since this is a mixin module */
963 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
964 if (ret)
965 return ret;
966
Jeeja KPce1b5552015-10-27 09:22:51 +0900967 for (i = 0; i < src_mconfig->max_out_queue; i++) {
968 if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) {
969 sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg;
970 if (!sink_mconfig)
971 continue;
972 /*
973 * This is a connecter and if path is found that means
974 * unbind between source and sink has not happened yet
975 */
Jeeja KPce1b5552015-10-27 09:22:51 +0900976 ret = skl_unbind_modules(ctx, src_mconfig,
977 sink_mconfig);
Vinod Kould93f8e52015-10-07 11:31:54 +0100978 }
979 }
980
Vinod Kould93f8e52015-10-07 11:31:54 +0100981 return ret;
982}
983
984/*
985 * In modelling, we assume there will be ONLY one mixer in a pipeline. If
986 * mixer is not required then it is treated as static mixer aka vmixer with
987 * a hard path to source module
988 * So we don't need to check if source is started or not as hard path puts
989 * dependency on each other
990 */
991static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
992 struct snd_kcontrol *k, int event)
993{
994 struct snd_soc_dapm_context *dapm = w->dapm;
995 struct skl *skl = get_skl_ctx(dapm->dev);
996
997 switch (event) {
998 case SND_SOC_DAPM_PRE_PMU:
999 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
1000
Jeeja KPde1fedf2016-02-03 17:59:52 +05301001 case SND_SOC_DAPM_POST_PMU:
1002 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
1003
1004 case SND_SOC_DAPM_PRE_PMD:
1005 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
1006
Vinod Kould93f8e52015-10-07 11:31:54 +01001007 case SND_SOC_DAPM_POST_PMD:
1008 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
1009 }
1010
1011 return 0;
1012}
1013
1014/*
1015 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
1016 * second one is required that is created as another pipe entity.
1017 * The mixer is responsible for pipe management and represent a pipeline
1018 * instance
1019 */
1020static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
1021 struct snd_kcontrol *k, int event)
1022{
1023 struct snd_soc_dapm_context *dapm = w->dapm;
1024 struct skl *skl = get_skl_ctx(dapm->dev);
1025
1026 switch (event) {
1027 case SND_SOC_DAPM_PRE_PMU:
1028 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
1029
1030 case SND_SOC_DAPM_POST_PMU:
1031 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
1032
1033 case SND_SOC_DAPM_PRE_PMD:
1034 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
1035
1036 case SND_SOC_DAPM_POST_PMD:
1037 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
1038 }
1039
1040 return 0;
1041}
1042
1043/*
1044 * In modelling, we assumed rest of the modules in pipeline are PGA. But we
1045 * are interested in last PGA (leaf PGA) in a pipeline to disconnect with
1046 * the sink when it is running (two FE to one BE or one FE to two BE)
1047 * scenarios
1048 */
1049static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
1050 struct snd_kcontrol *k, int event)
1051
1052{
1053 struct snd_soc_dapm_context *dapm = w->dapm;
1054 struct skl *skl = get_skl_ctx(dapm->dev);
1055
1056 switch (event) {
1057 case SND_SOC_DAPM_PRE_PMU:
1058 return skl_tplg_pga_dapm_pre_pmu_event(w, skl);
1059
1060 case SND_SOC_DAPM_POST_PMD:
1061 return skl_tplg_pga_dapm_post_pmd_event(w, skl);
1062 }
1063
1064 return 0;
1065}
Vinod Koulcfb0a872015-10-07 11:31:55 +01001066
Jeeja KP140adfb2015-11-28 15:01:50 +05301067static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
1068 unsigned int __user *data, unsigned int size)
1069{
1070 struct soc_bytes_ext *sb =
1071 (struct soc_bytes_ext *)kcontrol->private_value;
1072 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
Omair M Abdullah7d9f2912015-12-03 23:29:56 +05301073 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
1074 struct skl_module_cfg *mconfig = w->priv;
1075 struct skl *skl = get_skl_ctx(w->dapm->dev);
1076
1077 if (w->power)
1078 skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
Dharageswari R0d682102016-07-08 18:15:03 +05301079 bc->size, bc->param_id, mconfig);
Jeeja KP140adfb2015-11-28 15:01:50 +05301080
Vinod Koul41556f62016-02-03 17:59:44 +05301081 /* decrement size for TLV header */
1082 size -= 2 * sizeof(u32);
1083
1084 /* check size as we don't want to send kernel data */
1085 if (size > bc->max)
1086 size = bc->max;
1087
Jeeja KP140adfb2015-11-28 15:01:50 +05301088 if (bc->params) {
1089 if (copy_to_user(data, &bc->param_id, sizeof(u32)))
1090 return -EFAULT;
Dan Carpentere8bc3c92015-12-08 08:53:22 +03001091 if (copy_to_user(data + 1, &size, sizeof(u32)))
Jeeja KP140adfb2015-11-28 15:01:50 +05301092 return -EFAULT;
Dan Carpentere8bc3c92015-12-08 08:53:22 +03001093 if (copy_to_user(data + 2, bc->params, size))
Jeeja KP140adfb2015-11-28 15:01:50 +05301094 return -EFAULT;
1095 }
1096
1097 return 0;
1098}
1099
1100#define SKL_PARAM_VENDOR_ID 0xff
1101
1102static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1103 const unsigned int __user *data, unsigned int size)
1104{
1105 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
1106 struct skl_module_cfg *mconfig = w->priv;
1107 struct soc_bytes_ext *sb =
1108 (struct soc_bytes_ext *)kcontrol->private_value;
1109 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
1110 struct skl *skl = get_skl_ctx(w->dapm->dev);
1111
1112 if (ac->params) {
Dharageswari R0d682102016-07-08 18:15:03 +05301113 if (size > ac->max)
1114 return -EINVAL;
1115
1116 ac->size = size;
Jeeja KP140adfb2015-11-28 15:01:50 +05301117 /*
1118 * if the param_is is of type Vendor, firmware expects actual
1119 * parameter id and size from the control.
1120 */
1121 if (ac->param_id == SKL_PARAM_VENDOR_ID) {
1122 if (copy_from_user(ac->params, data, size))
1123 return -EFAULT;
1124 } else {
1125 if (copy_from_user(ac->params,
Alan65b4bcb2016-02-19 11:42:32 +05301126 data + 2, size))
Jeeja KP140adfb2015-11-28 15:01:50 +05301127 return -EFAULT;
1128 }
1129
1130 if (w->power)
1131 return skl_set_module_params(skl->skl_sst,
Dharageswari R0d682102016-07-08 18:15:03 +05301132 (u32 *)ac->params, ac->size,
Jeeja KP140adfb2015-11-28 15:01:50 +05301133 ac->param_id, mconfig);
1134 }
1135
1136 return 0;
1137}
1138
Vinod Koulcfb0a872015-10-07 11:31:55 +01001139/*
Jeeja KP8871dcb2016-06-03 18:29:42 +05301140 * Fill the dma id for host and link. In case of passthrough
1141 * pipeline, this will both host and link in the same
1142 * pipeline, so need to copy the link and host based on dev_type
1143 */
1144static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg,
1145 struct skl_pipe_params *params)
1146{
1147 struct skl_pipe *pipe = mcfg->pipe;
1148
1149 if (pipe->passthru) {
1150 switch (mcfg->dev_type) {
1151 case SKL_DEVICE_HDALINK:
1152 pipe->p_params->link_dma_id = params->link_dma_id;
1153 break;
1154
1155 case SKL_DEVICE_HDAHOST:
1156 pipe->p_params->host_dma_id = params->host_dma_id;
1157 break;
1158
1159 default:
1160 break;
1161 }
1162 pipe->p_params->s_fmt = params->s_fmt;
1163 pipe->p_params->ch = params->ch;
1164 pipe->p_params->s_freq = params->s_freq;
1165 pipe->p_params->stream = params->stream;
1166
1167 } else {
1168 memcpy(pipe->p_params, params, sizeof(*params));
1169 }
1170}
1171
1172/*
Vinod Koulcfb0a872015-10-07 11:31:55 +01001173 * The FE params are passed by hw_params of the DAI.
1174 * On hw_params, the params are stored in Gateway module of the FE and we
1175 * need to calculate the format in DSP module configuration, that
1176 * conversion is done here
1177 */
1178int skl_tplg_update_pipe_params(struct device *dev,
1179 struct skl_module_cfg *mconfig,
1180 struct skl_pipe_params *params)
1181{
Vinod Koulcfb0a872015-10-07 11:31:55 +01001182 struct skl_module_fmt *format = NULL;
1183
Jeeja KP8871dcb2016-06-03 18:29:42 +05301184 skl_tplg_fill_dma_id(mconfig, params);
Vinod Koulcfb0a872015-10-07 11:31:55 +01001185
1186 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
Hardik T Shah4cd98992015-10-27 09:22:55 +09001187 format = &mconfig->in_fmt[0];
Vinod Koulcfb0a872015-10-07 11:31:55 +01001188 else
Hardik T Shah4cd98992015-10-27 09:22:55 +09001189 format = &mconfig->out_fmt[0];
Vinod Koulcfb0a872015-10-07 11:31:55 +01001190
1191 /* set the hw_params */
1192 format->s_freq = params->s_freq;
1193 format->channels = params->ch;
1194 format->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
1195
1196 /*
1197 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
1198 * container so update bit depth accordingly
1199 */
1200 switch (format->valid_bit_depth) {
1201 case SKL_DEPTH_16BIT:
1202 format->bit_depth = format->valid_bit_depth;
1203 break;
1204
1205 case SKL_DEPTH_24BIT:
Jeeja KP6654f392015-10-27 09:22:46 +09001206 case SKL_DEPTH_32BIT:
Vinod Koulcfb0a872015-10-07 11:31:55 +01001207 format->bit_depth = SKL_DEPTH_32BIT;
1208 break;
1209
1210 default:
1211 dev_err(dev, "Invalid bit depth %x for pipe\n",
1212 format->valid_bit_depth);
1213 return -EINVAL;
1214 }
1215
1216 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1217 mconfig->ibs = (format->s_freq / 1000) *
1218 (format->channels) *
1219 (format->bit_depth >> 3);
1220 } else {
1221 mconfig->obs = (format->s_freq / 1000) *
1222 (format->channels) *
1223 (format->bit_depth >> 3);
1224 }
1225
1226 return 0;
1227}
1228
1229/*
1230 * Query the module config for the FE DAI
1231 * This is used to find the hw_params set for that DAI and apply to FE
1232 * pipeline
1233 */
1234struct skl_module_cfg *
1235skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
1236{
1237 struct snd_soc_dapm_widget *w;
1238 struct snd_soc_dapm_path *p = NULL;
1239
1240 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1241 w = dai->playback_widget;
Subhransu S. Prustyf0900eb2015-10-22 23:22:36 +05301242 snd_soc_dapm_widget_for_each_sink_path(w, p) {
Vinod Koulcfb0a872015-10-07 11:31:55 +01001243 if (p->connect && p->sink->power &&
Jeeja KPa28f51d2015-10-27 09:22:44 +09001244 !is_skl_dsp_widget_type(p->sink))
Vinod Koulcfb0a872015-10-07 11:31:55 +01001245 continue;
1246
1247 if (p->sink->priv) {
1248 dev_dbg(dai->dev, "set params for %s\n",
1249 p->sink->name);
1250 return p->sink->priv;
1251 }
1252 }
1253 } else {
1254 w = dai->capture_widget;
Subhransu S. Prustyf0900eb2015-10-22 23:22:36 +05301255 snd_soc_dapm_widget_for_each_source_path(w, p) {
Vinod Koulcfb0a872015-10-07 11:31:55 +01001256 if (p->connect && p->source->power &&
Jeeja KPa28f51d2015-10-27 09:22:44 +09001257 !is_skl_dsp_widget_type(p->source))
Vinod Koulcfb0a872015-10-07 11:31:55 +01001258 continue;
1259
1260 if (p->source->priv) {
1261 dev_dbg(dai->dev, "set params for %s\n",
1262 p->source->name);
1263 return p->source->priv;
1264 }
1265 }
1266 }
1267
1268 return NULL;
1269}
1270
Dharageswari.R718a42b2016-02-05 12:19:06 +05301271static struct skl_module_cfg *skl_get_mconfig_pb_cpr(
1272 struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
1273{
1274 struct snd_soc_dapm_path *p;
1275 struct skl_module_cfg *mconfig = NULL;
1276
1277 snd_soc_dapm_widget_for_each_source_path(w, p) {
1278 if (w->endpoints[SND_SOC_DAPM_DIR_OUT] > 0) {
1279 if (p->connect &&
1280 (p->sink->id == snd_soc_dapm_aif_out) &&
1281 p->source->priv) {
1282 mconfig = p->source->priv;
1283 return mconfig;
1284 }
1285 mconfig = skl_get_mconfig_pb_cpr(dai, p->source);
1286 if (mconfig)
1287 return mconfig;
1288 }
1289 }
1290 return mconfig;
1291}
1292
1293static struct skl_module_cfg *skl_get_mconfig_cap_cpr(
1294 struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
1295{
1296 struct snd_soc_dapm_path *p;
1297 struct skl_module_cfg *mconfig = NULL;
1298
1299 snd_soc_dapm_widget_for_each_sink_path(w, p) {
1300 if (w->endpoints[SND_SOC_DAPM_DIR_IN] > 0) {
1301 if (p->connect &&
1302 (p->source->id == snd_soc_dapm_aif_in) &&
1303 p->sink->priv) {
1304 mconfig = p->sink->priv;
1305 return mconfig;
1306 }
1307 mconfig = skl_get_mconfig_cap_cpr(dai, p->sink);
1308 if (mconfig)
1309 return mconfig;
1310 }
1311 }
1312 return mconfig;
1313}
1314
1315struct skl_module_cfg *
1316skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, int stream)
1317{
1318 struct snd_soc_dapm_widget *w;
1319 struct skl_module_cfg *mconfig;
1320
1321 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1322 w = dai->playback_widget;
1323 mconfig = skl_get_mconfig_pb_cpr(dai, w);
1324 } else {
1325 w = dai->capture_widget;
1326 mconfig = skl_get_mconfig_cap_cpr(dai, w);
1327 }
1328 return mconfig;
1329}
1330
Vinod Koulcfb0a872015-10-07 11:31:55 +01001331static u8 skl_tplg_be_link_type(int dev_type)
1332{
1333 int ret;
1334
1335 switch (dev_type) {
1336 case SKL_DEVICE_BT:
1337 ret = NHLT_LINK_SSP;
1338 break;
1339
1340 case SKL_DEVICE_DMIC:
1341 ret = NHLT_LINK_DMIC;
1342 break;
1343
1344 case SKL_DEVICE_I2S:
1345 ret = NHLT_LINK_SSP;
1346 break;
1347
1348 case SKL_DEVICE_HDALINK:
1349 ret = NHLT_LINK_HDA;
1350 break;
1351
1352 default:
1353 ret = NHLT_LINK_INVALID;
1354 break;
1355 }
1356
1357 return ret;
1358}
1359
1360/*
1361 * Fill the BE gateway parameters
1362 * The BE gateway expects a blob of parameters which are kept in the ACPI
1363 * NHLT blob, so query the blob for interface type (i2s/pdm) and instance.
1364 * The port can have multiple settings so pick based on the PCM
1365 * parameters
1366 */
1367static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
1368 struct skl_module_cfg *mconfig,
1369 struct skl_pipe_params *params)
1370{
Vinod Koulcfb0a872015-10-07 11:31:55 +01001371 struct nhlt_specific_cfg *cfg;
1372 struct skl *skl = get_skl_ctx(dai->dev);
1373 int link_type = skl_tplg_be_link_type(mconfig->dev_type);
1374
Jeeja KP8871dcb2016-06-03 18:29:42 +05301375 skl_tplg_fill_dma_id(mconfig, params);
Vinod Koulcfb0a872015-10-07 11:31:55 +01001376
Jeeja KPb30c2752015-10-27 09:22:48 +09001377 if (link_type == NHLT_LINK_HDA)
1378 return 0;
1379
Vinod Koulcfb0a872015-10-07 11:31:55 +01001380 /* update the blob based on virtual bus_id*/
1381 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
1382 params->s_fmt, params->ch,
1383 params->s_freq, params->stream);
1384 if (cfg) {
1385 mconfig->formats_config.caps_size = cfg->size;
Jeeja KPbc032812015-10-22 23:22:35 +05301386 mconfig->formats_config.caps = (u32 *) &cfg->caps;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001387 } else {
1388 dev_err(dai->dev, "Blob NULL for id %x type %d dirn %d\n",
1389 mconfig->vbus_id, link_type,
1390 params->stream);
1391 dev_err(dai->dev, "PCM: ch %d, freq %d, fmt %d\n",
1392 params->ch, params->s_freq, params->s_fmt);
1393 return -EINVAL;
1394 }
1395
1396 return 0;
1397}
1398
1399static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
1400 struct snd_soc_dapm_widget *w,
1401 struct skl_pipe_params *params)
1402{
1403 struct snd_soc_dapm_path *p;
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301404 int ret = -EIO;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001405
Subhransu S. Prustyf0900eb2015-10-22 23:22:36 +05301406 snd_soc_dapm_widget_for_each_source_path(w, p) {
Vinod Koulcfb0a872015-10-07 11:31:55 +01001407 if (p->connect && is_skl_dsp_widget_type(p->source) &&
1408 p->source->priv) {
1409
Jeeja KP9a03cb42015-10-27 09:22:54 +09001410 ret = skl_tplg_be_fill_pipe_params(dai,
1411 p->source->priv, params);
1412 if (ret < 0)
1413 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001414 } else {
Jeeja KP9a03cb42015-10-27 09:22:54 +09001415 ret = skl_tplg_be_set_src_pipe_params(dai,
1416 p->source, params);
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301417 if (ret < 0)
1418 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001419 }
1420 }
1421
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301422 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001423}
1424
1425static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
1426 struct snd_soc_dapm_widget *w, struct skl_pipe_params *params)
1427{
1428 struct snd_soc_dapm_path *p = NULL;
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301429 int ret = -EIO;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001430
Subhransu S. Prustyf0900eb2015-10-22 23:22:36 +05301431 snd_soc_dapm_widget_for_each_sink_path(w, p) {
Vinod Koulcfb0a872015-10-07 11:31:55 +01001432 if (p->connect && is_skl_dsp_widget_type(p->sink) &&
1433 p->sink->priv) {
1434
Jeeja KP9a03cb42015-10-27 09:22:54 +09001435 ret = skl_tplg_be_fill_pipe_params(dai,
1436 p->sink->priv, params);
1437 if (ret < 0)
1438 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001439 } else {
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301440 ret = skl_tplg_be_set_sink_pipe_params(
Vinod Koulcfb0a872015-10-07 11:31:55 +01001441 dai, p->sink, params);
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301442 if (ret < 0)
1443 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001444 }
1445 }
1446
Subhransu S. Prusty4d8adccb2015-10-22 23:22:37 +05301447 return ret;
Vinod Koulcfb0a872015-10-07 11:31:55 +01001448}
1449
1450/*
1451 * BE hw_params can be a source parameters (capture) or sink parameters
1452 * (playback). Based on sink and source we need to either find the source
1453 * list or the sink list and set the pipeline parameters
1454 */
1455int skl_tplg_be_update_params(struct snd_soc_dai *dai,
1456 struct skl_pipe_params *params)
1457{
1458 struct snd_soc_dapm_widget *w;
1459
1460 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1461 w = dai->playback_widget;
1462
1463 return skl_tplg_be_set_src_pipe_params(dai, w, params);
1464
1465 } else {
1466 w = dai->capture_widget;
1467
1468 return skl_tplg_be_set_sink_pipe_params(dai, w, params);
1469 }
1470
1471 return 0;
1472}
Vinod Koul3af36702015-10-07 11:31:56 +01001473
1474static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1475 {SKL_MIXER_EVENT, skl_tplg_mixer_event},
1476 {SKL_VMIXER_EVENT, skl_tplg_vmixer_event},
1477 {SKL_PGA_EVENT, skl_tplg_pga_event},
1478};
1479
Jeeja KP140adfb2015-11-28 15:01:50 +05301480static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1481 {SKL_CONTROL_TYPE_BYTE_TLV, skl_tplg_tlv_control_get,
1482 skl_tplg_tlv_control_set},
1483};
1484
Vinod Koul3af36702015-10-07 11:31:56 +01001485/*
1486 * The topology binary passes the pin info for a module so initialize the pin
1487 * info passed into module instance
1488 */
Jeeja KP6abca1d2015-10-22 23:22:42 +05301489static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1490 struct skl_module_pin *m_pin,
1491 bool is_dynamic, int max_pin)
Vinod Koul3af36702015-10-07 11:31:56 +01001492{
1493 int i;
1494
1495 for (i = 0; i < max_pin; i++) {
Jeeja KP6abca1d2015-10-22 23:22:42 +05301496 m_pin[i].id.module_id = dfw_pin[i].module_id;
1497 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
Vinod Koul3af36702015-10-07 11:31:56 +01001498 m_pin[i].in_use = false;
Jeeja KP6abca1d2015-10-22 23:22:42 +05301499 m_pin[i].is_dynamic = is_dynamic;
Jeeja KP4f745702015-10-27 09:22:49 +09001500 m_pin[i].pin_state = SKL_PIN_UNBIND;
Vinod Koul3af36702015-10-07 11:31:56 +01001501 }
1502}
1503
1504/*
1505 * Add pipeline from topology binary into driver pipeline list
1506 *
1507 * If already added we return that instance
1508 * Otherwise we create a new instance and add into driver list
1509 */
1510static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
1511 struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
1512{
1513 struct skl_pipeline *ppl;
1514 struct skl_pipe *pipe;
1515 struct skl_pipe_params *params;
1516
1517 list_for_each_entry(ppl, &skl->ppl_list, node) {
1518 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
1519 return ppl->pipe;
1520 }
1521
1522 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
1523 if (!ppl)
1524 return NULL;
1525
1526 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
1527 if (!pipe)
1528 return NULL;
1529
1530 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
1531 if (!params)
1532 return NULL;
1533
1534 pipe->ppl_id = dfw_pipe->pipe_id;
1535 pipe->memory_pages = dfw_pipe->memory_pages;
1536 pipe->pipe_priority = dfw_pipe->pipe_priority;
1537 pipe->conn_type = dfw_pipe->conn_type;
1538 pipe->state = SKL_PIPE_INVALID;
1539 pipe->p_params = params;
1540 INIT_LIST_HEAD(&pipe->w_list);
1541
1542 ppl->pipe = pipe;
1543 list_add(&ppl->node, &skl->ppl_list);
1544
1545 return ppl->pipe;
1546}
1547
Hardik T Shah4cd98992015-10-27 09:22:55 +09001548static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
1549 struct skl_dfw_module_fmt *src_fmt,
1550 int pins)
1551{
1552 int i;
1553
1554 for (i = 0; i < pins; i++) {
1555 dst_fmt[i].channels = src_fmt[i].channels;
1556 dst_fmt[i].s_freq = src_fmt[i].freq;
1557 dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
1558 dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
1559 dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
1560 dst_fmt[i].ch_map = src_fmt[i].ch_map;
1561 dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
1562 dst_fmt[i].sample_type = src_fmt[i].sample_type;
1563 }
1564}
1565
Dharageswari Rfe3f4442016-06-03 18:29:39 +05301566static void skl_clear_pin_config(struct snd_soc_platform *platform,
1567 struct snd_soc_dapm_widget *w)
1568{
1569 int i;
1570 struct skl_module_cfg *mconfig;
1571 struct skl_pipe *pipe;
1572
1573 if (!strncmp(w->dapm->component->name, platform->component.name,
1574 strlen(platform->component.name))) {
1575 mconfig = w->priv;
1576 pipe = mconfig->pipe;
1577 for (i = 0; i < mconfig->max_in_queue; i++) {
1578 mconfig->m_in_pin[i].in_use = false;
1579 mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND;
1580 }
1581 for (i = 0; i < mconfig->max_out_queue; i++) {
1582 mconfig->m_out_pin[i].in_use = false;
1583 mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND;
1584 }
1585 pipe->state = SKL_PIPE_INVALID;
1586 mconfig->m_state = SKL_MODULE_UNINIT;
1587 }
1588}
1589
1590void skl_cleanup_resources(struct skl *skl)
1591{
1592 struct skl_sst *ctx = skl->skl_sst;
1593 struct snd_soc_platform *soc_platform = skl->platform;
1594 struct snd_soc_dapm_widget *w;
1595 struct snd_soc_card *card;
1596
1597 if (soc_platform == NULL)
1598 return;
1599
1600 card = soc_platform->component.card;
1601 if (!card || !card->instantiated)
1602 return;
1603
1604 skl->resource.mem = 0;
1605 skl->resource.mcps = 0;
1606
1607 list_for_each_entry(w, &card->widgets, list) {
1608 if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
1609 skl_clear_pin_config(soc_platform, w);
1610 }
1611
1612 skl_clear_module_cnt(ctx->dsp);
1613}
1614
Vinod Koul3af36702015-10-07 11:31:56 +01001615/*
1616 * Topology core widget load callback
1617 *
1618 * This is used to save the private data for each widget which gives
1619 * information to the driver about module and pipeline parameters which DSP
1620 * FW expects like ids, resource values, formats etc
1621 */
1622static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
Jeeja KPb663a8c2015-10-07 11:31:57 +01001623 struct snd_soc_dapm_widget *w,
1624 struct snd_soc_tplg_dapm_widget *tplg_w)
Vinod Koul3af36702015-10-07 11:31:56 +01001625{
1626 int ret;
1627 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1628 struct skl *skl = ebus_to_skl(ebus);
1629 struct hdac_bus *bus = ebus_to_hbus(ebus);
1630 struct skl_module_cfg *mconfig;
1631 struct skl_pipe *pipe;
Jeeja KPb663a8c2015-10-07 11:31:57 +01001632 struct skl_dfw_module *dfw_config =
1633 (struct skl_dfw_module *)tplg_w->priv.data;
Vinod Koul3af36702015-10-07 11:31:56 +01001634
1635 if (!tplg_w->priv.size)
1636 goto bind_event;
1637
1638 mconfig = devm_kzalloc(bus->dev, sizeof(*mconfig), GFP_KERNEL);
1639
1640 if (!mconfig)
1641 return -ENOMEM;
1642
1643 w->priv = mconfig;
Shreyas NC09305da2016-04-21 11:45:22 +05301644 memcpy(&mconfig->guid, &dfw_config->uuid, 16);
1645
Vinod Koulb7c50552016-07-26 18:06:40 +05301646 /*
1647 * module binary can be loaded later, so set it to query when
1648 * module is load for a use case
1649 */
1650 mconfig->id.module_id = -1;
Vinod Koul3af36702015-10-07 11:31:56 +01001651 mconfig->id.instance_id = dfw_config->instance_id;
1652 mconfig->mcps = dfw_config->max_mcps;
1653 mconfig->ibs = dfw_config->ibs;
1654 mconfig->obs = dfw_config->obs;
1655 mconfig->core_id = dfw_config->core_id;
1656 mconfig->max_in_queue = dfw_config->max_in_queue;
1657 mconfig->max_out_queue = dfw_config->max_out_queue;
1658 mconfig->is_loadable = dfw_config->is_loadable;
Hardik T Shah4cd98992015-10-27 09:22:55 +09001659 skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
1660 MODULE_MAX_IN_PINS);
1661 skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
1662 MODULE_MAX_OUT_PINS);
1663
Vinod Koul3af36702015-10-07 11:31:56 +01001664 mconfig->params_fixup = dfw_config->params_fixup;
1665 mconfig->converter = dfw_config->converter;
1666 mconfig->m_type = dfw_config->module_type;
1667 mconfig->vbus_id = dfw_config->vbus_id;
Jeeja KPb18c4582015-12-03 23:29:51 +05301668 mconfig->mem_pages = dfw_config->mem_pages;
Vinod Koul3af36702015-10-07 11:31:56 +01001669
1670 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1671 if (pipe)
1672 mconfig->pipe = pipe;
1673
1674 mconfig->dev_type = dfw_config->dev_type;
1675 mconfig->hw_conn_type = dfw_config->hw_conn_type;
1676 mconfig->time_slot = dfw_config->time_slot;
1677 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1678
Hardik T Shah4cd98992015-10-27 09:22:55 +09001679 mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
1680 sizeof(*mconfig->m_in_pin),
1681 GFP_KERNEL);
Vinod Koul3af36702015-10-07 11:31:56 +01001682 if (!mconfig->m_in_pin)
1683 return -ENOMEM;
1684
Jeeja KP6abca1d2015-10-22 23:22:42 +05301685 mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
1686 sizeof(*mconfig->m_out_pin),
1687 GFP_KERNEL);
Vinod Koul3af36702015-10-07 11:31:56 +01001688 if (!mconfig->m_out_pin)
1689 return -ENOMEM;
1690
Jeeja KP6abca1d2015-10-22 23:22:42 +05301691 skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
1692 dfw_config->is_dynamic_in_pin,
1693 mconfig->max_in_queue);
1694
1695 skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
1696 dfw_config->is_dynamic_out_pin,
1697 mconfig->max_out_queue);
1698
Vinod Koul3af36702015-10-07 11:31:56 +01001699
1700 if (mconfig->formats_config.caps_size == 0)
1701 goto bind_event;
1702
1703 mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
Jeeja KPb663a8c2015-10-07 11:31:57 +01001704 mconfig->formats_config.caps_size, GFP_KERNEL);
Vinod Koul3af36702015-10-07 11:31:56 +01001705
1706 if (mconfig->formats_config.caps == NULL)
1707 return -ENOMEM;
1708
1709 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
Jeeja KPabb74002015-11-28 15:01:49 +05301710 dfw_config->caps.caps_size);
1711 mconfig->formats_config.param_id = dfw_config->caps.param_id;
1712 mconfig->formats_config.set_params = dfw_config->caps.set_params;
Vinod Koul3af36702015-10-07 11:31:56 +01001713
1714bind_event:
1715 if (tplg_w->event_type == 0) {
Vinod Koul3373f712015-10-07 16:39:38 +01001716 dev_dbg(bus->dev, "ASoC: No event handler required\n");
Vinod Koul3af36702015-10-07 11:31:56 +01001717 return 0;
1718 }
1719
1720 ret = snd_soc_tplg_widget_bind_event(w, skl_tplg_widget_ops,
Jeeja KPb663a8c2015-10-07 11:31:57 +01001721 ARRAY_SIZE(skl_tplg_widget_ops),
1722 tplg_w->event_type);
Vinod Koul3af36702015-10-07 11:31:56 +01001723
1724 if (ret) {
1725 dev_err(bus->dev, "%s: No matching event handlers found for %d\n",
1726 __func__, tplg_w->event_type);
1727 return -EINVAL;
1728 }
1729
1730 return 0;
1731}
1732
Jeeja KP140adfb2015-11-28 15:01:50 +05301733static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
1734 struct snd_soc_tplg_bytes_control *bc)
1735{
1736 struct skl_algo_data *ac;
1737 struct skl_dfw_algo_data *dfw_ac =
1738 (struct skl_dfw_algo_data *)bc->priv.data;
1739
1740 ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
1741 if (!ac)
1742 return -ENOMEM;
1743
1744 /* Fill private data */
1745 ac->max = dfw_ac->max;
1746 ac->param_id = dfw_ac->param_id;
1747 ac->set_params = dfw_ac->set_params;
Dharageswari R0d682102016-07-08 18:15:03 +05301748 ac->size = dfw_ac->max;
Jeeja KP140adfb2015-11-28 15:01:50 +05301749
1750 if (ac->max) {
1751 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL);
1752 if (!ac->params)
1753 return -ENOMEM;
1754
Alan Coxedd7ea22016-02-22 09:37:27 +05301755 memcpy(ac->params, dfw_ac->params, ac->max);
Jeeja KP140adfb2015-11-28 15:01:50 +05301756 }
1757
1758 be->dobj.private = ac;
1759 return 0;
1760}
1761
1762static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1763 struct snd_kcontrol_new *kctl,
1764 struct snd_soc_tplg_ctl_hdr *hdr)
1765{
1766 struct soc_bytes_ext *sb;
1767 struct snd_soc_tplg_bytes_control *tplg_bc;
1768 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1769 struct hdac_bus *bus = ebus_to_hbus(ebus);
1770
1771 switch (hdr->ops.info) {
1772 case SND_SOC_TPLG_CTL_BYTES:
1773 tplg_bc = container_of(hdr,
1774 struct snd_soc_tplg_bytes_control, hdr);
1775 if (kctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1776 sb = (struct soc_bytes_ext *)kctl->private_value;
1777 if (tplg_bc->priv.size)
1778 return skl_init_algo_data(
1779 bus->dev, sb, tplg_bc);
1780 }
1781 break;
1782
1783 default:
1784 dev_warn(bus->dev, "Control load not supported %d:%d:%d\n",
1785 hdr->ops.get, hdr->ops.put, hdr->ops.info);
1786 break;
1787 }
1788
1789 return 0;
1790}
1791
Kranthi G15ecaba92016-07-26 18:06:43 +05301792static int skl_manifest_load(struct snd_soc_component *cmpnt,
1793 struct snd_soc_tplg_manifest *manifest)
1794{
1795 struct skl_dfw_manifest *minfo;
1796 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1797 struct hdac_bus *bus = ebus_to_hbus(ebus);
1798 struct skl *skl = ebus_to_skl(ebus);
1799 int ret = 0;
1800
1801 minfo = &skl->skl_sst->manifest;
1802 memcpy(minfo, manifest->priv.data, sizeof(struct skl_dfw_manifest));
1803
1804 if (minfo->lib_count > HDA_MAX_LIB) {
1805 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
1806 minfo->lib_count);
1807 ret = -EINVAL;
1808 }
1809
1810 return ret;
1811}
1812
Vinod Koul3af36702015-10-07 11:31:56 +01001813static struct snd_soc_tplg_ops skl_tplg_ops = {
1814 .widget_load = skl_tplg_widget_load,
Jeeja KP140adfb2015-11-28 15:01:50 +05301815 .control_load = skl_tplg_control_load,
1816 .bytes_ext_ops = skl_tlv_ops,
1817 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
Kranthi G15ecaba92016-07-26 18:06:43 +05301818 .manifest = skl_manifest_load,
Vinod Koul3af36702015-10-07 11:31:56 +01001819};
1820
Jeeja KP287af4f2016-06-03 18:29:40 +05301821/*
1822 * A pipe can have multiple modules, each of them will be a DAPM widget as
1823 * well. While managing a pipeline we need to get the list of all the
1824 * widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
1825 * helps to get the SKL type widgets in that pipeline
1826 */
1827static int skl_tplg_create_pipe_widget_list(struct snd_soc_platform *platform)
1828{
1829 struct snd_soc_dapm_widget *w;
1830 struct skl_module_cfg *mcfg = NULL;
1831 struct skl_pipe_module *p_module = NULL;
1832 struct skl_pipe *pipe;
1833
1834 list_for_each_entry(w, &platform->component.card->widgets, list) {
1835 if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
1836 mcfg = w->priv;
1837 pipe = mcfg->pipe;
1838
1839 p_module = devm_kzalloc(platform->dev,
1840 sizeof(*p_module), GFP_KERNEL);
1841 if (!p_module)
1842 return -ENOMEM;
1843
1844 p_module->w = w;
1845 list_add_tail(&p_module->node, &pipe->w_list);
1846 }
1847 }
1848
1849 return 0;
1850}
1851
Jeeja KPf0aa94f2016-06-03 18:29:41 +05301852static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
1853{
1854 struct skl_pipe_module *w_module;
1855 struct snd_soc_dapm_widget *w;
1856 struct skl_module_cfg *mconfig;
1857 bool host_found = false, link_found = false;
1858
1859 list_for_each_entry(w_module, &pipe->w_list, node) {
1860 w = w_module->w;
1861 mconfig = w->priv;
1862
1863 if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
1864 host_found = true;
1865 else if (mconfig->dev_type != SKL_DEVICE_NONE)
1866 link_found = true;
1867 }
1868
1869 if (host_found && link_found)
1870 pipe->passthru = true;
1871 else
1872 pipe->passthru = false;
1873}
1874
Vinod Koul3af36702015-10-07 11:31:56 +01001875/* This will be read from topology manifest, currently defined here */
1876#define SKL_MAX_MCPS 30000000
1877#define SKL_FW_MAX_MEM 1000000
1878
1879/*
1880 * SKL topology init routine
1881 */
1882int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
1883{
1884 int ret;
1885 const struct firmware *fw;
1886 struct hdac_bus *bus = ebus_to_hbus(ebus);
1887 struct skl *skl = ebus_to_skl(ebus);
Jeeja KPf0aa94f2016-06-03 18:29:41 +05301888 struct skl_pipeline *ppl;
Vinod Koul3af36702015-10-07 11:31:56 +01001889
Vinod Koul4b235c42016-02-19 11:42:34 +05301890 ret = request_firmware(&fw, skl->tplg_name, bus->dev);
Vinod Koul3af36702015-10-07 11:31:56 +01001891 if (ret < 0) {
Jeeja KPb663a8c2015-10-07 11:31:57 +01001892 dev_err(bus->dev, "tplg fw %s load failed with %d\n",
Vinod Koul4b235c42016-02-19 11:42:34 +05301893 skl->tplg_name, ret);
1894 ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
1895 if (ret < 0) {
1896 dev_err(bus->dev, "Fallback tplg fw %s load failed with %d\n",
1897 "dfw_sst.bin", ret);
1898 return ret;
1899 }
Vinod Koul3af36702015-10-07 11:31:56 +01001900 }
1901
1902 /*
1903 * The complete tplg for SKL is loaded as index 0, we don't use
1904 * any other index
1905 */
Jeeja KPb663a8c2015-10-07 11:31:57 +01001906 ret = snd_soc_tplg_component_load(&platform->component,
1907 &skl_tplg_ops, fw, 0);
Vinod Koul3af36702015-10-07 11:31:56 +01001908 if (ret < 0) {
1909 dev_err(bus->dev, "tplg component load failed%d\n", ret);
Sudip Mukherjeec14a82c2016-01-21 17:27:59 +05301910 release_firmware(fw);
Vinod Koul3af36702015-10-07 11:31:56 +01001911 return -EINVAL;
1912 }
1913
1914 skl->resource.max_mcps = SKL_MAX_MCPS;
1915 skl->resource.max_mem = SKL_FW_MAX_MEM;
1916
Vinod Kould8018362016-01-05 17:16:04 +05301917 skl->tplg = fw;
Jeeja KP287af4f2016-06-03 18:29:40 +05301918 ret = skl_tplg_create_pipe_widget_list(platform);
1919 if (ret < 0)
1920 return ret;
Vinod Kould8018362016-01-05 17:16:04 +05301921
Jeeja KPf0aa94f2016-06-03 18:29:41 +05301922 list_for_each_entry(ppl, &skl->ppl_list, node)
1923 skl_tplg_set_pipe_type(skl, ppl->pipe);
Vinod Koul3af36702015-10-07 11:31:56 +01001924
1925 return 0;
Jeeja KPe4e2d2f2015-10-07 11:31:52 +01001926}