aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/apple/mca.c79
-rw-r--r--sound/soc/codecs/wm_adsp.c4
-rw-r--r--sound/soc/sof/sof-audio.c29
3 files changed, 78 insertions, 34 deletions
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
index aa67d57c9a9b..69643524796e 100644
--- a/sound/soc/apple/mca.c
+++ b/sound/soc/apple/mca.c
@@ -885,6 +885,43 @@ static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
return snd_dmaengine_pcm_pointer(substream);
}
+static struct dma_chan *mca_request_dma_channel(struct mca_cluster *cl, unsigned int stream)
+{
+ bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+#ifndef USE_RXB_FOR_CAPTURE
+ char *name = devm_kasprintf(cl->host->dev, GFP_KERNEL,
+ is_tx ? "tx%da" : "rx%da", cl->no);
+#else
+ char *name = devm_kasprintf(cl->host->dev, GFP_KERNEL,
+ is_tx ? "tx%da" : "rx%db", cl->no);
+#endif
+ return of_dma_request_slave_channel(cl->host->dev->of_node, name);
+
+}
+
+static void mca_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_pcm_chip(pcm);
+ struct mca_cluster *cl = mca_dai_to_cluster(asoc_rtd_to_cpu(rtd, 0));
+ unsigned int i;
+
+ if (rtd->dai_link->no_pcm)
+ return;
+
+ for_each_pcm_streams(i) {
+ struct snd_pcm_substream *substream =
+ rtd->pcm->streams[i].substream;
+
+ if (!substream || !cl->dma_chans[i])
+ continue;
+
+ dma_release_channel(cl->dma_chans[i]);
+ cl->dma_chans[i] = NULL;
+ }
+}
+
+
static int mca_pcm_new(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd)
{
@@ -897,17 +934,21 @@ static int mca_pcm_new(struct snd_soc_component *component,
for_each_pcm_streams(i) {
struct snd_pcm_substream *substream =
rtd->pcm->streams[i].substream;
- struct dma_chan *chan = cl->dma_chans[i];
+ struct dma_chan *chan;
if (!substream)
continue;
- if (!chan) {
- dev_err(component->dev, "missing DMA channel for stream %d on SERDES %d\n",
- i, cl->no);
+ chan = mca_request_dma_channel(cl, i);
+
+ if (IS_ERR_OR_NULL(chan)) {
+ dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
+ i, cl->no, chan);
+ mca_pcm_free(component, rtd->pcm);
return -EINVAL;
}
+ cl->dma_chans[i] = chan;
snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV_IRAM,
chan->device->dev, 512 * 1024 * 6,
SIZE_MAX);
@@ -924,6 +965,7 @@ static const struct snd_soc_component_driver mca_component = {
.trigger = mca_trigger,
.pointer = mca_pointer,
.pcm_construct = mca_pcm_new,
+ .pcm_destruct = mca_pcm_free,
};
static void apple_mca_release(struct mca_data *mca)
@@ -1019,7 +1061,6 @@ static int apple_mca_probe(struct platform_device *pdev)
struct snd_soc_dai_driver *fe =
&dai_drivers[mca->nclusters + i];
struct snd_soc_dai_driver *be = &dai_drivers[i];
- int stream;
cl->host = mca;
cl->no = i;
@@ -1041,34 +1082,6 @@ static int apple_mca_probe(struct platform_device *pdev)
goto err_release;
}
- for_each_pcm_streams(stream) {
- struct dma_chan *chan;
- bool is_tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
-#ifndef USE_RXB_FOR_CAPTURE
- char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
- is_tx ? "tx%da" : "rx%da",
- i);
-#else
- char *name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
- is_tx ? "tx%da" : "rx%db",
- i);
-#endif
-
- chan = of_dma_request_slave_channel(pdev->dev.of_node,
- name);
- if (IS_ERR(chan)) {
- if (PTR_ERR(chan) != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "no %s DMA channel: %ld\n",
- name, PTR_ERR(chan));
-
- ret = PTR_ERR(chan);
- goto err_release;
- }
-
- cl->dma_chans[stream] = chan;
- }
-
fe->id = i;
fe->name =
devm_kasprintf(&pdev->dev, GFP_KERNEL, "mca-pcm-%d", i);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index cfaa45ede916..8a2e9771bb50 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1602,7 +1602,9 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
if (list_empty(&dsp->buffer_list)) {
/* Fall back to legacy support */
ret = wm_adsp_buffer_parse_legacy(dsp);
- if (ret)
+ if (ret == -ENODEV)
+ adsp_info(dsp, "Legacy support not available\n");
+ else if (ret)
adsp_warn(dsp, "Failed to parse legacy: %d\n", ret);
}
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index c18e723435bd..ea9663d448eb 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -785,6 +785,28 @@ int sof_dai_get_bclk(struct snd_soc_pcm_runtime *rtd)
}
EXPORT_SYMBOL(sof_dai_get_bclk);
+static struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *sof_pdata = sdev->pdata;
+ const struct sof_dev_desc *desc = sof_pdata->desc;
+ struct snd_sof_of_mach *mach = desc->of_machines;
+
+ if (!mach)
+ return NULL;
+
+ for (; mach->compatible; mach++) {
+ if (of_machine_is_compatible(mach->compatible)) {
+ sof_pdata->tplg_filename = mach->sof_tplg_filename;
+ if (mach->fw_filename)
+ sof_pdata->fw_filename = mach->fw_filename;
+
+ return mach;
+ }
+ }
+
+ return NULL;
+}
+
/*
* SOF Driver enumeration.
*/
@@ -795,6 +817,7 @@ int sof_machine_check(struct snd_sof_dev *sdev)
struct snd_soc_acpi_mach *mach;
if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) {
+ const struct snd_sof_of_mach *of_mach;
/* find machine */
mach = snd_sof_machine_select(sdev);
@@ -804,6 +827,12 @@ int sof_machine_check(struct snd_sof_dev *sdev)
return 0;
}
+ of_mach = sof_of_machine_select(sdev);
+ if (of_mach) {
+ sof_pdata->of_machine = of_mach;
+ return 0;
+ }
+
if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) {
dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n");
return -ENODEV;