Skip to content

Commit 8a2e4a7

Browse files
ranj063broonie
authored andcommitted
ASoC: SOF: topology: Make pga widget parsing IPC agnostic
Define the list of tokens pertaining to the pga type widgets, parse and save them as part of the swidget tuples array. Once topology parsing is complete, these tokens will be applied to create the IPC structure for the pga component based on the topology widget_setup op in ipc3_tplg_ops. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20220314200520.1233427-9-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 6bd0be1 commit 8a2e4a7

2 files changed

Lines changed: 86 additions & 83 deletions

File tree

sound/soc/sof/ipc3-topology.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ static const struct sof_topology_token pipeline_tokens[] = {
4343

4444
};
4545

46+
/* volume */
47+
static const struct sof_topology_token volume_tokens[] = {
48+
{SOF_TKN_VOLUME_RAMP_STEP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
49+
offsetof(struct sof_ipc_comp_volume, ramp)},
50+
{SOF_TKN_VOLUME_RAMP_STEP_MS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
51+
offsetof(struct sof_ipc_comp_volume, initial_ramp)},
52+
};
53+
4654
/* PCM */
4755
static const struct sof_topology_token pcm_tokens[] = {
4856
{SOF_TKN_PCM_DMAC_CONFIG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@@ -80,6 +88,7 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = {
8088
[SOF_CORE_TOKENS] = {"Core tokens", core_tokens, ARRAY_SIZE(core_tokens)},
8189
[SOF_COMP_EXT_TOKENS] = {"AFE tokens", comp_ext_tokens, ARRAY_SIZE(comp_ext_tokens)},
8290
[SOF_BUFFER_TOKENS] = {"Buffer tokens", buffer_tokens, ARRAY_SIZE(buffer_tokens)},
91+
[SOF_VOLUME_TOKENS] = {"Volume tokens", volume_tokens, ARRAY_SIZE(volume_tokens)},
8392
};
8493

8594
/**
@@ -281,6 +290,66 @@ static int sof_ipc3_widget_setup_comp_buffer(struct snd_sof_widget *swidget)
281290
return 0;
282291
}
283292

293+
/*
294+
* PGA Topology
295+
*/
296+
297+
static int sof_ipc3_widget_setup_comp_pga(struct snd_sof_widget *swidget)
298+
{
299+
struct snd_soc_component *scomp = swidget->scomp;
300+
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
301+
struct sof_ipc_comp_volume *volume;
302+
struct snd_sof_control *scontrol;
303+
size_t ipc_size = sizeof(*volume);
304+
int min_step, max_step;
305+
int ret;
306+
307+
volume = sof_comp_alloc(swidget, &ipc_size, swidget->pipeline_id);
308+
if (!volume)
309+
return -ENOMEM;
310+
311+
swidget->private = volume;
312+
313+
/* configure volume IPC message */
314+
volume->comp.type = SOF_COMP_VOLUME;
315+
volume->config.hdr.size = sizeof(volume->config);
316+
317+
/* parse one set of volume tokens */
318+
ret = sof_update_ipc_object(scomp, volume, SOF_VOLUME_TOKENS, swidget->tuples,
319+
swidget->num_tuples, sizeof(*volume), 1);
320+
if (ret < 0)
321+
goto err;
322+
323+
/* parse one set of comp tokens */
324+
ret = sof_update_ipc_object(scomp, &volume->config, SOF_COMP_TOKENS,
325+
swidget->tuples, swidget->num_tuples,
326+
sizeof(volume->config), 1);
327+
if (ret < 0)
328+
goto err;
329+
330+
dev_dbg(scomp->dev, "loaded PGA %s\n", swidget->widget->name);
331+
sof_dbg_comp_config(scomp, &volume->config);
332+
333+
list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
334+
if (scontrol->comp_id == swidget->comp_id &&
335+
scontrol->volume_table) {
336+
min_step = scontrol->min_volume_step;
337+
max_step = scontrol->max_volume_step;
338+
volume->min_value = scontrol->volume_table[min_step];
339+
volume->max_value = scontrol->volume_table[max_step];
340+
volume->channels = scontrol->num_channels;
341+
break;
342+
}
343+
}
344+
345+
return 0;
346+
err:
347+
kfree(swidget->private);
348+
swidget->private = NULL;
349+
350+
return ret;
351+
}
352+
284353
/* token list for each topology object */
285354
static enum sof_tokens host_token_list[] = {
286355
SOF_CORE_TOKENS,
@@ -300,6 +369,13 @@ static enum sof_tokens pipeline_token_list[] = {
300369
SOF_SCHED_TOKENS,
301370
};
302371

372+
static enum sof_tokens pga_token_list[] = {
373+
SOF_CORE_TOKENS,
374+
SOF_COMP_EXT_TOKENS,
375+
SOF_VOLUME_TOKENS,
376+
SOF_COMP_TOKENS,
377+
};
378+
303379
static const struct sof_ipc_tplg_widget_ops tplg_ipc3_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = {
304380
[snd_soc_dapm_aif_in] = {sof_ipc3_widget_setup_comp_host, sof_ipc3_widget_free_comp,
305381
host_token_list, ARRAY_SIZE(host_token_list), NULL},
@@ -309,6 +385,8 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc3_widget_ops[SND_SOC_DAPM_TY
309385
buffer_token_list, ARRAY_SIZE(buffer_token_list), NULL},
310386
[snd_soc_dapm_scheduler] = {sof_ipc3_widget_setup_comp_pipeline, sof_ipc3_widget_free_comp,
311387
pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL},
388+
[snd_soc_dapm_pga] = {sof_ipc3_widget_setup_comp_pga, sof_ipc3_widget_free_comp,
389+
pga_token_list, ARRAY_SIZE(pga_token_list), NULL},
312390
};
313391

314392
static const struct sof_ipc_tplg_ops ipc3_tplg_ops = {

sound/soc/sof/topology.c

Lines changed: 8 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,6 @@ static const struct sof_topology_token dai_link_tokens[] = {
629629
offsetof(struct sof_ipc_dai_config, dai_index)},
630630
};
631631

632-
/* volume */
633-
static const struct sof_topology_token volume_tokens[] = {
634-
{SOF_TKN_VOLUME_RAMP_STEP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
635-
get_token_u32, offsetof(struct sof_ipc_comp_volume, ramp)},
636-
{SOF_TKN_VOLUME_RAMP_STEP_MS,
637-
SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
638-
offsetof(struct sof_ipc_comp_volume, initial_ramp)},
639-
};
640-
641632
/* SRC */
642633
static const struct sof_topology_token src_tokens[] = {
643634
{SOF_TKN_SRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@@ -1878,78 +1869,6 @@ static int sof_widget_load_mux(struct snd_soc_component *scomp, int index,
18781869
return 0;
18791870
}
18801871

1881-
/*
1882-
* PGA Topology
1883-
*/
1884-
1885-
static int sof_widget_load_pga(struct snd_soc_component *scomp, int index,
1886-
struct snd_sof_widget *swidget,
1887-
struct snd_soc_tplg_dapm_widget *tw)
1888-
{
1889-
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
1890-
struct snd_soc_tplg_private *private = &tw->priv;
1891-
struct sof_ipc_comp_volume *volume;
1892-
struct snd_sof_control *scontrol;
1893-
size_t ipc_size = sizeof(*volume);
1894-
int min_step;
1895-
int max_step;
1896-
int ret;
1897-
1898-
volume = (struct sof_ipc_comp_volume *)
1899-
sof_comp_alloc(swidget, &ipc_size, index);
1900-
if (!volume)
1901-
return -ENOMEM;
1902-
1903-
if (!le32_to_cpu(tw->num_kcontrols)) {
1904-
dev_err(scomp->dev, "error: invalid kcontrol count %d for volume\n",
1905-
tw->num_kcontrols);
1906-
ret = -EINVAL;
1907-
goto err;
1908-
}
1909-
1910-
/* configure volume IPC message */
1911-
volume->comp.type = SOF_COMP_VOLUME;
1912-
volume->config.hdr.size = sizeof(volume->config);
1913-
1914-
ret = sof_parse_tokens(scomp, volume, volume_tokens,
1915-
ARRAY_SIZE(volume_tokens), private->array,
1916-
le32_to_cpu(private->size));
1917-
if (ret != 0) {
1918-
dev_err(scomp->dev, "error: parse volume tokens failed %d\n",
1919-
private->size);
1920-
goto err;
1921-
}
1922-
ret = sof_parse_tokens(scomp, &volume->config, comp_tokens,
1923-
ARRAY_SIZE(comp_tokens), private->array,
1924-
le32_to_cpu(private->size));
1925-
if (ret != 0) {
1926-
dev_err(scomp->dev, "error: parse volume.cfg tokens failed %d\n",
1927-
le32_to_cpu(private->size));
1928-
goto err;
1929-
}
1930-
1931-
sof_dbg_comp_config(scomp, &volume->config);
1932-
1933-
swidget->private = volume;
1934-
1935-
list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
1936-
if (scontrol->comp_id == swidget->comp_id &&
1937-
scontrol->volume_table) {
1938-
min_step = scontrol->min_volume_step;
1939-
max_step = scontrol->max_volume_step;
1940-
volume->min_value = scontrol->volume_table[min_step];
1941-
volume->max_value = scontrol->volume_table[max_step];
1942-
volume->channels = scontrol->num_channels;
1943-
break;
1944-
}
1945-
}
1946-
1947-
return 0;
1948-
err:
1949-
kfree(volume);
1950-
return ret;
1951-
}
1952-
19531872
/*
19541873
* SRC Topology
19551874
*/
@@ -2426,8 +2345,14 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
24262345
ret = sof_widget_load_mixer(scomp, index, swidget, tw);
24272346
break;
24282347
case snd_soc_dapm_pga:
2429-
ret = sof_widget_load_pga(scomp, index, swidget, tw);
2430-
break;
2348+
if (!le32_to_cpu(tw->num_kcontrols)) {
2349+
dev_err(scomp->dev, "invalid kcontrol count %d for volume\n",
2350+
tw->num_kcontrols);
2351+
ret = -EINVAL;
2352+
break;
2353+
}
2354+
2355+
fallthrough;
24312356
case snd_soc_dapm_buffer:
24322357
case snd_soc_dapm_scheduler:
24332358
case snd_soc_dapm_aif_out:

0 commit comments

Comments
 (0)