ASoC: SOF: Intel: hda: add SoundWire stream config/free callbacks

These callbacks are invoked when a matching hw_params/hw_free() DAI
operation takes place, and will result in IPC operations with the SOF
firmware.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200325215027.28716-5-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Pierre-Louis Bossart 2020-03-25 16:50:20 -05:00 committed by Mark Brown
parent f8e2501880
commit d2c383aa49
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 71 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#include <sound/intel-nhlt.h> #include <sound/intel-nhlt.h>
#include <sound/sof.h> #include <sound/sof.h>
#include <sound/sof/xtensa.h> #include <sound/sof/xtensa.h>
#include "../sof-audio.h"
#include "../ops.h" #include "../ops.h"
#include "hda.h" #include "hda.h"
@ -38,6 +39,74 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
static int sdw_params_stream(struct device *dev,
struct sdw_intel_stream_params_data *params_data)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_soc_dai *d = params_data->dai;
struct sof_ipc_dai_config config;
struct sof_ipc_reply reply;
int link_id = params_data->link_id;
int alh_stream_id = params_data->alh_stream_id;
int ret;
u32 size = sizeof(config);
memset(&config, 0, size);
config.hdr.size = size;
config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG;
config.type = SOF_DAI_INTEL_ALH;
config.dai_index = (link_id << 8) | (d->id);
config.alh.stream_id = alh_stream_id;
/* send message to DSP */
ret = sof_ipc_tx_message(sdev->ipc,
config.hdr.cmd, &config, size, &reply,
sizeof(reply));
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to set DAI hw_params for link %d dai->id %d ALH %d\n",
link_id, d->id, alh_stream_id);
}
return ret;
}
static int sdw_free_stream(struct device *dev,
struct sdw_intel_stream_free_data *free_data)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_soc_dai *d = free_data->dai;
struct sof_ipc_dai_config config;
struct sof_ipc_reply reply;
int link_id = free_data->link_id;
int ret;
u32 size = sizeof(config);
memset(&config, 0, size);
config.hdr.size = size;
config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG;
config.type = SOF_DAI_INTEL_ALH;
config.dai_index = (link_id << 8) | d->id;
config.alh.stream_id = 0xFFFF; /* invalid value on purpose */
/* send message to DSP */
ret = sof_ipc_tx_message(sdev->ipc,
config.hdr.cmd, &config, size, &reply,
sizeof(reply));
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to free stream for link %d dai->id %d\n",
link_id, d->id);
}
return ret;
}
static const struct sdw_intel_ops sdw_callback = {
.params_stream = sdw_params_stream,
.free_stream = sdw_free_stream,
};
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
{ {
sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable); sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable);
@ -80,6 +149,8 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
res.irq = sdev->ipc_irq; res.irq = sdev->ipc_irq;
res.handle = hdev->info.handle; res.handle = hdev->info.handle;
res.parent = sdev->dev; res.parent = sdev->dev;
res.ops = &sdw_callback;
res.dev = sdev->dev;
/* /*
* ops and arg fields are not populated for now, * ops and arg fields are not populated for now,