summaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/compress.c15
-rw-r--r--sound/soc/sof/intel/hda-stream.c10
-rw-r--r--sound/soc/sof/intel/hda.c17
-rw-r--r--sound/soc/sof/ipc4-topology.c13
-rw-r--r--sound/soc/sof/pcm.c10
-rw-r--r--sound/soc/sof/sof-audio.h13
-rw-r--r--sound/soc/sof/sof-priv.h2
-rw-r--r--sound/soc/sof/topology.c36
8 files changed, 68 insertions, 48 deletions
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c
index 96570121aae0..93f2376585db 100644
--- a/sound/soc/sof/compress.c
+++ b/sound/soc/sof/compress.c
@@ -247,14 +247,15 @@ static int sof_compr_set_params(struct snd_soc_component *component,
ret = snd_sof_set_stream_data_offset(sdev, &spcm->stream[cstream->direction],
ipc_params_reply.posn_offset);
if (ret < 0) {
- dev_err(component->dev, "Invalid stream data offset for Compr %d\n",
- spcm->pcm.pcm_id);
+ dev_err(component->dev, "Invalid stream data offset for Compr %u\n",
+ le32_to_cpu(spcm->pcm.pcm_id));
goto out;
}
sstream->sampling_rate = params->codec.sample_rate;
sstream->channels = params->codec.ch_out;
sstream->sample_container_bytes = pcm->params.sample_container_bytes;
+ sstream->codec_params = params->codec;
spcm->prepared[cstream->direction] = true;
@@ -267,9 +268,10 @@ out:
static int sof_compr_get_params(struct snd_soc_component *component,
struct snd_compr_stream *cstream, struct snd_codec *params)
{
- /* TODO: we don't query the supported codecs for now, if the
- * application asks for an unsupported codec the set_params() will fail.
- */
+ struct sof_compr_stream *sstream = cstream->runtime->private_data;
+
+ *params = sstream->codec_params;
+
return 0;
}
@@ -379,6 +381,9 @@ static int sof_compr_pointer(struct snd_soc_component *component,
if (!spcm)
return -EINVAL;
+ if (!sstream->channels || !sstream->sample_container_bytes)
+ return -EBUSY;
+
tstamp->sampling_rate = sstream->sampling_rate;
tstamp->copied_total = sstream->copied_total;
tstamp->pcm_io_frames = div_u64(spcm->stream[cstream->direction].posn.dai_posn,
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 1c04b5d9c0d8..5c1f3b427cdb 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -480,16 +480,20 @@ int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_st
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params)
{
- struct hdac_stream *hstream = &hext_stream->hstream;
- int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
+ struct hdac_stream *hstream;
+ int sd_offset;
int ret;
- u32 mask = 0x1 << hstream->index;
+ u32 mask;
if (!hext_stream) {
dev_err(sdev->dev, "error: no stream available\n");
return -ENODEV;
}
+ hstream = &hext_stream->hstream;
+ sd_offset = SOF_STREAM_SD_OFFSET(hstream);
+ mask = 0x1 << hstream->index;
+
if (!dmab) {
dev_err(sdev->dev, "error: no dma buffer allocated!\n");
return -ENODEV;
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 8a240dcb7fcb..b3d61d973ce4 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -1178,6 +1178,9 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
struct snd_soc_acpi_endpoint *endpoints;
int amp_group_id = 1;
+ if (sdw_device->id.mfg_id != codec_info_list[i].vendor_id)
+ continue;
+
if (sdw_device->id.part_id != codec_info_list[i].part_id)
continue;
@@ -1192,8 +1195,8 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
* dereference
*/
if (!name_prefix) {
- dev_err(dev, "codec_info_list name_prefix of part id %#x is missing\n",
- codec_info_list[i].part_id);
+ dev_err(dev, "codec_info_list name_prefix of part id %#x-%#x is missing\n",
+ codec_info_list[i].vendor_id, codec_info_list[i].part_id);
return NULL;
}
for (j = 0; j < codec_info_list[i].dai_num; j++) {
@@ -1227,6 +1230,16 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
return NULL;
}
+ /*
+ * codec_info_list[].is_amp is a codec-level override: for multi-function
+ * codecs we must treat the whole codec as an AMP when it is described as
+ * such in the codec info table, even if some endpoints were detected as
+ * non-AMP above. Callers/UCM rely on this to keep name_prefix and AMP
+ * indexing stable and backwards compatible.
+ */
+ if (codec_info_list[i].is_amp)
+ is_amp = true;
+
adr_dev[index].adr = ((u64)sdw_device->id.class_id & 0xFF) |
((u64)sdw_device->id.part_id & 0xFFFF) << 8 |
((u64)sdw_device->id.mfg_id & 0xFFFF) << 24 |
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index c12ffdcfe4e3..76812d8fb567 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -581,6 +581,7 @@ sof_ipc4_update_card_components_string(struct snd_sof_widget *swidget,
struct snd_soc_component *scomp = spcm->scomp;
struct snd_soc_card *card = scomp->card;
const char *pt_marker = "iec61937-pcm";
+ unsigned pcm_id = le32_to_cpu(spcm->pcm.pcm_id);
/*
* Update the card's components list with iec61937-pcm and a list of PCM
@@ -595,21 +596,21 @@ sof_ipc4_update_card_components_string(struct snd_sof_widget *swidget,
if (strstr(card->components, pt_marker))
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
- "%s,%d",
+ "%s,%u",
card->components,
- spcm->pcm.pcm_id);
+ pcm_id);
else
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
- "%s %s:%d",
+ "%s %s:%u",
card->components,
pt_marker,
- spcm->pcm.pcm_id);
+ pcm_id);
devm_kfree(card->dev, tmp);
} else {
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
- "%s:%d", pt_marker,
- spcm->pcm.pcm_id);
+ "%s:%u", pt_marker,
+ pcm_id);
}
if (!card->components)
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 5b598d0940eb..b2071edeaea6 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -360,8 +360,8 @@ static int sof_pcm_prepare(struct snd_soc_component *component,
platform_params = &spcm->platform_params[substream->stream];
ret = sof_widget_list_setup(sdev, spcm, params, platform_params, dir);
if (ret < 0) {
- dev_err(sdev->dev, "failed widget list set up for pcm %d dir %d\n",
- spcm->pcm.pcm_id, dir);
+ dev_err(sdev->dev, "failed widget list set up for pcm %d dir %u\n",
+ le32_to_cpu(spcm->pcm.pcm_id), dir);
spcm->stream[dir].list = NULL;
snd_soc_dapm_dai_free_widgets(&list);
return ret;
@@ -651,8 +651,8 @@ static int sof_pcm_new(struct snd_soc_component *component,
return 0;
}
- dev_dbg(spcm->scomp->dev, "pcm%u (%s): Entry: pcm_construct\n",
- spcm->pcm.pcm_id, spcm->pcm.pcm_name);
+ dev_dbg(spcm->scomp->dev, "pcm%u (%s): Entry: pcm_new\n",
+ le32_to_cpu(spcm->pcm.pcm_id), spcm->pcm.pcm_name);
/* do we need to pre-allocate playback audio buffer pages */
if (!spcm->pcm.playback)
@@ -850,7 +850,7 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)
pd->compress_ops = &sof_compressed_ops;
#endif
- pd->pcm_construct = sof_pcm_new;
+ pd->pcm_new = sof_pcm_new;
pd->ignore_machine = drv_name;
pd->be_pcm_base = SOF_BE_PCM_BASE;
pd->use_dai_pcm_id = true;
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 36082e764bf9..138e5fcc2dd0 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -411,11 +411,11 @@ struct snd_sof_dai_link {
struct snd_sof_tuple *tuples;
int num_tuples;
struct snd_soc_dai_link *link;
- struct snd_soc_tplg_hw_config *hw_configs;
int num_hw_configs;
int default_hw_cfg_id;
int type;
struct list_head list;
+ struct snd_soc_tplg_hw_config hw_configs[] __counted_by(num_hw_configs);
};
/* ASoC SOF DAPM widget */
@@ -641,17 +641,20 @@ void snd_sof_pcm_init_elapsed_work(struct work_struct *work);
*/
#define spcm_dbg(__spcm, __dir, __fmt, ...) \
dev_dbg((__spcm)->scomp->dev, "pcm%u (%s), dir %d: " __fmt, \
- (__spcm)->pcm.pcm_id, (__spcm)->pcm.pcm_name, __dir, \
+ le32_to_cpu((__spcm)->pcm.pcm_id), \
+ (__spcm)->pcm.pcm_name, __dir, \
##__VA_ARGS__)
#define spcm_dbg_ratelimited(__spcm, __dir, __fmt, ...) \
dev_dbg_ratelimited((__spcm)->scomp->dev, "pcm%u (%s), dir %d: " __fmt, \
- (__spcm)->pcm.pcm_id, (__spcm)->pcm.pcm_name, __dir, \
- ##__VA_ARGS__)
+ le32_to_cpu((__spcm)->pcm.pcm_id), \
+ (__spcm)->pcm.pcm_name, __dir, \
+ ##__VA_ARGS__)
#define spcm_err(__spcm, __dir, __fmt, ...) \
dev_err((__spcm)->scomp->dev, "%s: pcm%u (%s), dir %d: " __fmt, \
- __func__, (__spcm)->pcm.pcm_id, (__spcm)->pcm.pcm_name, __dir, \
+ __func__, le32_to_cpu((__spcm)->pcm.pcm_id), \
+ (__spcm)->pcm.pcm_name, __dir, \
##__VA_ARGS__)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS)
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 693d063830fa..38753b088fc1 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -17,6 +17,7 @@
#include <sound/sof/info.h>
#include <sound/sof/pm.h>
#include <sound/sof/trace.h>
+#include <sound/compress_params.h>
#include <uapi/sound/sof/fw.h>
#include <sound/sof/ext_manifest.h>
@@ -111,6 +112,7 @@ struct sof_compr_stream {
u32 sampling_rate;
u16 channels;
u16 sample_container_bytes;
+ struct snd_codec codec_params;
size_t posn_offset;
};
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 35200d801fb7..63d582c65891 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -775,8 +775,8 @@ static int sof_parse_token_sets(struct snd_soc_component *scomp,
array);
break;
default:
- dev_err(scomp->dev, "error: unknown token type %d\n",
- array->type);
+ dev_err(scomp->dev, "error: unknown token type %u\n",
+ le32_to_cpu(array->type));
return -EINVAL;
}
@@ -880,7 +880,7 @@ skip:
ARRAY_SIZE(led_tokens), mc->priv.array,
le32_to_cpu(mc->priv.size));
if (ret != 0) {
- dev_err(scomp->dev, "error: parse led tokens failed %d\n",
+ dev_err(scomp->dev, "error: parse led tokens failed %u\n",
le32_to_cpu(mc->priv.size));
goto err;
}
@@ -970,8 +970,8 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
struct snd_sof_control *scontrol;
int ret;
- dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n",
- hdr->type, hdr->name);
+ dev_dbg(scomp->dev, "tplg: load control type %u name : %s\n",
+ le32_to_cpu(hdr->type), hdr->name);
scontrol = kzalloc_obj(*scontrol);
if (!scontrol)
@@ -1015,8 +1015,10 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
case SND_SOC_TPLG_DAPM_CTL_PIN:
default:
- dev_warn(scomp->dev, "control type not supported %d:%d:%d\n",
- hdr->ops.get, hdr->ops.put, hdr->ops.info);
+ dev_warn(scomp->dev, "control type not supported %u:%u:%u\n",
+ le32_to_cpu(hdr->ops.get),
+ le32_to_cpu(hdr->ops.put),
+ le32_to_cpu(hdr->ops.info));
kfree(scontrol->name);
kfree(scontrol);
return 0;
@@ -1523,8 +1525,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
break;
case snd_soc_dapm_pga:
if (!le32_to_cpu(tw->num_kcontrols)) {
- dev_err(scomp->dev, "invalid kcontrol count %d for volume\n",
- tw->num_kcontrols);
+ dev_err(scomp->dev, "invalid kcontrol count %u for volume\n",
+ le32_to_cpu(tw->num_kcontrols));
ret = -EINVAL;
break;
}
@@ -1772,7 +1774,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
ARRAY_SIZE(stream_tokens), private->array,
le32_to_cpu(private->size));
if (ret) {
- dev_err(scomp->dev, "error: parse stream tokens failed %d\n",
+ dev_err(scomp->dev, "error: parse stream tokens failed %u\n",
le32_to_cpu(private->size));
return ret;
}
@@ -1906,18 +1908,12 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
return -EINVAL;
}
- slink = kzalloc_obj(*slink);
+ slink = kzalloc_flex(*slink, hw_configs, le32_to_cpu(cfg->num_hw_configs));
if (!slink)
return -ENOMEM;
slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs);
- slink->hw_configs = kmemdup_array(cfg->hw_config,
- slink->num_hw_configs, sizeof(*slink->hw_configs),
- GFP_KERNEL);
- if (!slink->hw_configs) {
- kfree(slink);
- return -ENOMEM;
- }
+ memcpy(slink->hw_configs, cfg->hw_config, le32_to_cpu(cfg->num_hw_configs) * sizeof(*slink->hw_configs));
slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id);
slink->link = link;
@@ -1930,7 +1926,6 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
private->array, le32_to_cpu(private->size));
if (ret < 0) {
dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n");
- kfree(slink->hw_configs);
kfree(slink);
return ret;
}
@@ -2001,7 +1996,6 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
/* allocate memory for tuples array */
slink->tuples = kzalloc_objs(*slink->tuples, num_tuples);
if (!slink->tuples) {
- kfree(slink->hw_configs);
kfree(slink);
return -ENOMEM;
}
@@ -2059,7 +2053,6 @@ out:
err:
kfree(slink->tuples);
- kfree(slink->hw_configs);
kfree(slink);
return ret;
@@ -2076,7 +2069,6 @@ static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj
kfree(slink->tuples);
list_del(&slink->list);
- kfree(slink->hw_configs);
kfree(slink);
dobj->private = NULL;