Commit 233d2c4a authored by Mark Brown's avatar Mark Brown

Clean ups and preparation for IPC abstraction in the SOF driver

Merge series from Ranjani Sridharan <ranjani.sridharan@linux.intel.com>:

In preparation for adding support for the new IPC version that has been
introduced in the SOF firmware, this patch set includes some clean ups
and necessary modifications to commonly used functions that will be
re-used across different IPC-specific code.
parents efb1a2d3 f535880b
...@@ -116,4 +116,9 @@ struct sof_ipc_dai_config { ...@@ -116,4 +116,9 @@ struct sof_ipc_dai_config {
}; };
} __packed; } __packed;
struct sof_dai_private_data {
struct sof_ipc_comp_dai *comp_dai;
struct sof_ipc_dai_config *dai_config;
};
#endif #endif
...@@ -87,9 +87,6 @@ struct sof_ipc_comp { ...@@ -87,9 +87,6 @@ struct sof_ipc_comp {
*/ */
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1) #define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
/* the UUID size in bytes, shared between FW and host */
#define SOF_UUID_SIZE 16
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */ /* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
struct sof_ipc_buffer { struct sof_ipc_buffer {
struct sof_ipc_comp comp; struct sof_ipc_comp comp;
...@@ -303,9 +300,4 @@ enum sof_event_types { ...@@ -303,9 +300,4 @@ enum sof_event_types {
SOF_KEYWORD_DETECT_DAPM_EVENT, SOF_KEYWORD_DETECT_DAPM_EVENT,
}; };
/* extended data struct for UUID components */
struct sof_ipc_comp_ext {
uint8_t uuid[SOF_UUID_SIZE];
} __packed;
#endif #endif
...@@ -167,6 +167,7 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg ...@@ -167,6 +167,7 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg
int channel) int channel)
{ {
struct snd_sof_widget *swidget = w->dobj.private; struct snd_sof_widget *swidget = w->dobj.private;
struct sof_dai_private_data *private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct snd_sof_dai *sof_dai; struct snd_sof_dai *sof_dai;
...@@ -175,12 +176,19 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg ...@@ -175,12 +176,19 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg
sof_dai = swidget->private; sof_dai = swidget->private;
if (!sof_dai || !sof_dai->dai_config) { if (!sof_dai || !sof_dai->private) {
dev_err(swidget->scomp->dev, "error: No config for DAI %s\n", w->name); dev_err(swidget->scomp->dev, "%s: No private data for DAI %s\n", __func__,
w->name);
return NULL; return NULL;
} }
config = &sof_dai->dai_config[sof_dai->current_config]; private = sof_dai->private;
if (!private->dai_config) {
dev_err(swidget->scomp->dev, "%s: No config for DAI %s\n", __func__, w->name);
return NULL;
}
config = &private->dai_config[sof_dai->current_config];
/* update config with stream tag */ /* update config with stream tag */
config->hda.link_dma_ch = channel; config->hda.link_dma_ch = channel;
...@@ -294,6 +302,7 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w) ...@@ -294,6 +302,7 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)
struct snd_sof_widget *swidget = w->dobj.private; struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp; struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_dai_private_data *private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct snd_sof_dai *sof_dai; struct snd_sof_dai *sof_dai;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
...@@ -301,12 +310,18 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w) ...@@ -301,12 +310,18 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)
sof_dai = swidget->private; sof_dai = swidget->private;
if (!sof_dai || !sof_dai->dai_config) { if (!sof_dai || !sof_dai->private) {
dev_err(sdev->dev, "No config for DAI %s\n", w->name); dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
return -EINVAL;
}
private = sof_dai->private;
if (!private->dai_config) {
dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
return -EINVAL; return -EINVAL;
} }
config = &sof_dai->dai_config[sof_dai->current_config]; config = &private->dai_config[sof_dai->current_config];
/* set PAUSE command flag */ /* set PAUSE command flag */
config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_CMD_MASK, SOF_DAI_CONFIG_FLAGS_PAUSE); config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_CMD_MASK, SOF_DAI_CONFIG_FLAGS_PAUSE);
......
...@@ -47,14 +47,21 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_ ...@@ -47,14 +47,21 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_
struct snd_soc_component *component = swidget->scomp; struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct sof_dai_private_data *private;
struct snd_sof_dai *sof_dai; struct snd_sof_dai *sof_dai;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
int ret; int ret;
sof_dai = swidget->private; sof_dai = swidget->private;
if (!sof_dai || !sof_dai->dai_config) { if (!sof_dai || !sof_dai->private) {
dev_err(sdev->dev, "No config for DAI %s\n", w->name); dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
return -EINVAL;
}
private = sof_dai->private;
if (!private->dai_config) {
dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
return -EINVAL; return -EINVAL;
} }
...@@ -65,7 +72,7 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_ ...@@ -65,7 +72,7 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_
return ret; return ret;
} }
config = &sof_dai->dai_config[sof_dai->current_config]; config = &private->dai_config[sof_dai->current_config];
/* /*
* For static pipelines, the DAI widget would already be set up and calling * For static pipelines, the DAI widget would already be set up and calling
...@@ -101,6 +108,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f ...@@ -101,6 +108,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f
struct snd_sof_widget *swidget = w->dobj.private; struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp; struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_dai_private_data *private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct snd_sof_dai *sof_dai; struct snd_sof_dai *sof_dai;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
...@@ -108,8 +116,14 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f ...@@ -108,8 +116,14 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f
sof_dai = swidget->private; sof_dai = swidget->private;
if (!sof_dai || !sof_dai->dai_config) { if (!sof_dai || !sof_dai->private) {
dev_err(sdev->dev, "error: No config to free DAI %s\n", w->name); dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
return -EINVAL;
}
private = sof_dai->private;
if (!private->dai_config) {
dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
return -EINVAL; return -EINVAL;
} }
...@@ -117,7 +131,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f ...@@ -117,7 +131,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f
if (!sof_dai->configured) if (!sof_dai->configured)
return 0; return 0;
config = &sof_dai->dai_config[sof_dai->current_config]; config = &private->dai_config[sof_dai->current_config];
/* set HW_FREE flag along with any quirks */ /* set HW_FREE flag along with any quirks */
config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE | config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE |
...@@ -154,6 +168,7 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev, ...@@ -154,6 +168,7 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
int link_id, int alh_stream_id, int dai_id, bool setup) int link_id, int alh_stream_id, int dai_id, bool setup)
{ {
struct snd_sof_widget *swidget = w->dobj.private; struct snd_sof_widget *swidget = w->dobj.private;
struct sof_dai_private_data *private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct snd_sof_dai *sof_dai; struct snd_sof_dai *sof_dai;
...@@ -164,12 +179,18 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev, ...@@ -164,12 +179,18 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
sof_dai = swidget->private; sof_dai = swidget->private;
if (!sof_dai || !sof_dai->dai_config) { if (!sof_dai || !sof_dai->private) {
dev_err(sdev->dev, "error: No config for DAI %s\n", w->name); dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
return -EINVAL;
}
private = sof_dai->private;
if (!private->dai_config) {
dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
return -EINVAL; return -EINVAL;
} }
config = &sof_dai->dai_config[sof_dai->current_config]; config = &private->dai_config[sof_dai->current_config];
/* update config with link and stream ID */ /* update config with link and stream ID */
config->dai_index = (link_id << 8) | dai_id; config->dai_index = (link_id << 8) | dai_id;
......
...@@ -27,18 +27,6 @@ static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf); ...@@ -27,18 +27,6 @@ static void ipc_stream_message(struct snd_sof_dev *sdev, void *msg_buf);
* IPC message Tx/Rx message handling. * IPC message Tx/Rx message handling.
*/ */
/* SOF generic IPC data */
struct snd_sof_ipc {
struct snd_sof_dev *sdev;
/* protects messages and the disable flag */
struct mutex tx_mutex;
/* disables further sending of ipc's */
bool disable_ipc_tx;
struct snd_sof_ipc_msg msg;
};
struct sof_ipc_ctrl_data_params { struct sof_ipc_ctrl_data_params {
size_t msg_bytes; size_t msg_bytes;
size_t hdr_bytes; size_t hdr_bytes;
......
...@@ -670,7 +670,9 @@ static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char ...@@ -670,7 +670,9 @@ static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char
if (!dai->name || strcmp(link_name, dai->name)) if (!dai->name || strcmp(link_name, dai->name))
continue; continue;
for (i = 0; i < dai->number_configs; i++) { for (i = 0; i < dai->number_configs; i++) {
config = &dai->dai_config[i]; struct sof_dai_private_data *private = dai->private;
config = &private->dai_config[i];
if (config->ssp.fsync_rate == params_rate(params)) { if (config->ssp.fsync_rate == params_rate(params)) {
dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i); dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i);
dai->current_config = i; dai->current_config = i;
...@@ -693,6 +695,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -693,6 +695,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
struct snd_sof_dai *dai = struct snd_sof_dai *dai =
snd_sof_find_dai(component, (char *)rtd->dai_link->name); snd_sof_find_dai(component, (char *)rtd->dai_link->name);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_dai_private_data *private = dai->private;
struct snd_soc_dpcm *dpcm; struct snd_soc_dpcm *dpcm;
/* no topology exists for this BE, try a common configuration */ /* no topology exists for this BE, try a common configuration */
...@@ -717,7 +720,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -717,7 +720,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
/* read format from topology */ /* read format from topology */
snd_mask_none(fmt); snd_mask_none(fmt);
switch (dai->comp_dai->config.frame_fmt) { switch (private->comp_dai->config.frame_fmt) {
case SOF_IPC_FRAME_S16_LE: case SOF_IPC_FRAME_S16_LE:
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
break; break;
...@@ -733,15 +736,15 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -733,15 +736,15 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
} }
/* read rate and channels from topology */ /* read rate and channels from topology */
switch (dai->dai_config->type) { switch (private->dai_config->type) {
case SOF_DAI_INTEL_SSP: case SOF_DAI_INTEL_SSP:
/* search for config to pcm params match, if not found use default */ /* search for config to pcm params match, if not found use default */
ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params); ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
rate->min = dai->dai_config[dai->current_config].ssp.fsync_rate; rate->min = private->dai_config[dai->current_config].ssp.fsync_rate;
rate->max = dai->dai_config[dai->current_config].ssp.fsync_rate; rate->max = private->dai_config[dai->current_config].ssp.fsync_rate;
channels->min = dai->dai_config[dai->current_config].ssp.tdm_slots; channels->min = private->dai_config[dai->current_config].ssp.tdm_slots;
channels->max = dai->dai_config[dai->current_config].ssp.tdm_slots; channels->max = private->dai_config[dai->current_config].ssp.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max); "rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -752,11 +755,11 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -752,11 +755,11 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
break; break;
case SOF_DAI_INTEL_DMIC: case SOF_DAI_INTEL_DMIC:
/* DMIC only supports 16 or 32 bit formats */ /* DMIC only supports 16 or 32 bit formats */
if (dai->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) { if (private->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
dev_err(component->dev, dev_err(component->dev,
"error: invalid fmt %d for DAI type %d\n", "error: invalid fmt %d for DAI type %d\n",
dai->comp_dai->config.frame_fmt, private->comp_dai->config.frame_fmt,
dai->dai_config->type); private->dai_config->type);
} }
break; break;
case SOF_DAI_INTEL_HDA: case SOF_DAI_INTEL_HDA:
...@@ -776,14 +779,14 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -776,14 +779,14 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
* Dai could run with different channel count compared with * Dai could run with different channel count compared with
* front end, so get dai channel count from topology * front end, so get dai channel count from topology
*/ */
channels->min = dai->dai_config->alh.channels; channels->min = private->dai_config->alh.channels;
channels->max = dai->dai_config->alh.channels; channels->max = private->dai_config->alh.channels;
break; break;
case SOF_DAI_IMX_ESAI: case SOF_DAI_IMX_ESAI:
rate->min = dai->dai_config->esai.fsync_rate; rate->min = private->dai_config->esai.fsync_rate;
rate->max = dai->dai_config->esai.fsync_rate; rate->max = private->dai_config->esai.fsync_rate;
channels->min = dai->dai_config->esai.tdm_slots; channels->min = private->dai_config->esai.tdm_slots;
channels->max = dai->dai_config->esai.tdm_slots; channels->max = private->dai_config->esai.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max); "rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -792,10 +795,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -792,10 +795,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min, channels->max); channels->min, channels->max);
break; break;
case SOF_DAI_MEDIATEK_AFE: case SOF_DAI_MEDIATEK_AFE:
rate->min = dai->dai_config->afe.rate; rate->min = private->dai_config->afe.rate;
rate->max = dai->dai_config->afe.rate; rate->max = private->dai_config->afe.rate;
channels->min = dai->dai_config->afe.channels; channels->min = private->dai_config->afe.channels;
channels->max = dai->dai_config->afe.channels; channels->max = private->dai_config->afe.channels;
dev_dbg(component->dev, dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max); "rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -804,10 +807,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -804,10 +807,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min, channels->max); channels->min, channels->max);
break; break;
case SOF_DAI_IMX_SAI: case SOF_DAI_IMX_SAI:
rate->min = dai->dai_config->sai.fsync_rate; rate->min = private->dai_config->sai.fsync_rate;
rate->max = dai->dai_config->sai.fsync_rate; rate->max = private->dai_config->sai.fsync_rate;
channels->min = dai->dai_config->sai.tdm_slots; channels->min = private->dai_config->sai.tdm_slots;
channels->max = dai->dai_config->sai.tdm_slots; channels->max = private->dai_config->sai.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max); "rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -816,10 +819,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -816,10 +819,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min, channels->max); channels->min, channels->max);
break; break;
case SOF_DAI_AMD_BT: case SOF_DAI_AMD_BT:
rate->min = dai->dai_config->acpbt.fsync_rate; rate->min = private->dai_config->acpbt.fsync_rate;
rate->max = dai->dai_config->acpbt.fsync_rate; rate->max = private->dai_config->acpbt.fsync_rate;
channels->min = dai->dai_config->acpbt.tdm_slots; channels->min = private->dai_config->acpbt.tdm_slots;
channels->max = dai->dai_config->acpbt.tdm_slots; channels->max = private->dai_config->acpbt.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max); "AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -828,10 +831,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -828,10 +831,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min, channels->max); channels->min, channels->max);
break; break;
case SOF_DAI_AMD_SP: case SOF_DAI_AMD_SP:
rate->min = dai->dai_config->acpsp.fsync_rate; rate->min = private->dai_config->acpsp.fsync_rate;
rate->max = dai->dai_config->acpsp.fsync_rate; rate->max = private->dai_config->acpsp.fsync_rate;
channels->min = dai->dai_config->acpsp.tdm_slots; channels->min = private->dai_config->acpsp.tdm_slots;
channels->max = dai->dai_config->acpsp.tdm_slots; channels->max = private->dai_config->acpsp.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max); "AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -840,10 +843,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -840,10 +843,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min, channels->max); channels->min, channels->max);
break; break;
case SOF_DAI_AMD_DMIC: case SOF_DAI_AMD_DMIC:
rate->min = dai->dai_config->acpdmic.fsync_rate; rate->min = private->dai_config->acpdmic.fsync_rate;
rate->max = dai->dai_config->acpdmic.fsync_rate; rate->max = private->dai_config->acpdmic.fsync_rate;
channels->min = dai->dai_config->acpdmic.tdm_slots; channels->min = private->dai_config->acpdmic.tdm_slots;
channels->max = dai->dai_config->acpdmic.tdm_slots; channels->max = private->dai_config->acpdmic.tdm_slots;
dev_dbg(component->dev, dev_dbg(component->dev,
"AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max); "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max);
...@@ -853,7 +856,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -853,7 +856,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
break; break;
default: default:
dev_err(component->dev, "error: invalid DAI type %d\n", dev_err(component->dev, "error: invalid DAI type %d\n",
dai->dai_config->type); private->dai_config->type);
break; break;
} }
......
...@@ -29,11 +29,12 @@ static int sof_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_control * ...@@ -29,11 +29,12 @@ static int sof_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_control *
static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *dai) static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *dai)
{ {
struct sof_dai_private_data *private = dai->private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
int ret; int ret;
config = &dai->dai_config[dai->current_config]; config = &private->dai_config[dai->current_config];
if (!config) { if (!config) {
dev_err(sdev->dev, "error: no config for DAI %s\n", dai->name); dev_err(sdev->dev, "error: no config for DAI %s\n", dai->name);
return -EINVAL; return -EINVAL;
...@@ -191,12 +192,16 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -191,12 +192,16 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
switch (swidget->id) { switch (swidget->id) {
case snd_soc_dapm_dai_in: case snd_soc_dapm_dai_in:
case snd_soc_dapm_dai_out: case snd_soc_dapm_dai_out:
{
struct sof_dai_private_data *dai_data;
dai = swidget->private; dai = swidget->private;
comp = &dai->comp_dai->comp; dai_data = dai->private;
comp = &dai_data->comp_dai->comp;
dai->configured = false; dai->configured = false;
ret = sof_ipc_tx_message(sdev->ipc, comp->hdr.cmd, dai->comp_dai, comp->hdr.size, ret = sof_ipc_tx_message(sdev->ipc, comp->hdr.cmd, dai_data->comp_dai,
&r, sizeof(r)); comp->hdr.size, &r, sizeof(r));
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "error: failed to load widget %s\n", dev_err(sdev->dev, "error: failed to load widget %s\n",
swidget->widget->name); swidget->widget->name);
...@@ -216,6 +221,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -216,6 +221,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
return ret; return ret;
} }
break; break;
}
case snd_soc_dapm_scheduler: case snd_soc_dapm_scheduler:
pipeline = swidget->private; pipeline = swidget->private;
ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline, ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline,
...@@ -259,28 +265,25 @@ EXPORT_SYMBOL(sof_widget_setup); ...@@ -259,28 +265,25 @@ EXPORT_SYMBOL(sof_widget_setup);
static int sof_route_setup_ipc(struct snd_sof_dev *sdev, struct snd_sof_route *sroute) static int sof_route_setup_ipc(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
{ {
struct sof_ipc_pipe_comp_connect *connect; struct sof_ipc_pipe_comp_connect connect;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
int ret; int ret;
/* skip if there's no private data */
if (!sroute->private)
return 0;
/* nothing to do if route is already set up */ /* nothing to do if route is already set up */
if (sroute->setup) if (sroute->setup)
return 0; return 0;
connect = sroute->private; connect.hdr.size = sizeof(connect);
connect.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_CONNECT;
connect.source_id = sroute->src_widget->comp_id;
connect.sink_id = sroute->sink_widget->comp_id;
dev_dbg(sdev->dev, "setting up route %s -> %s\n", dev_dbg(sdev->dev, "setting up route %s -> %s\n",
sroute->src_widget->widget->name, sroute->src_widget->widget->name,
sroute->sink_widget->widget->name); sroute->sink_widget->widget->name);
/* send ipc */ /* send ipc */
ret = sof_ipc_tx_message(sdev->ipc, ret = sof_ipc_tx_message(sdev->ipc, connect.hdr.cmd, &connect, sizeof(connect),
connect->hdr.cmd,
connect, sizeof(*connect),
&reply, sizeof(reply)); &reply, sizeof(reply));
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "%s: route setup failed %d\n", __func__, ret); dev_err(sdev->dev, "%s: route setup failed %d\n", __func__, ret);
...@@ -623,12 +626,13 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify) ...@@ -623,12 +626,13 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
/* update DAI config. The IPC will be sent in sof_widget_setup() */ /* update DAI config. The IPC will be sent in sof_widget_setup() */
if (WIDGET_IS_DAI(swidget->id)) { if (WIDGET_IS_DAI(swidget->id)) {
struct snd_sof_dai *dai = swidget->private; struct snd_sof_dai *dai = swidget->private;
struct sof_dai_private_data *private = dai->private;
struct sof_ipc_dai_config *config; struct sof_ipc_dai_config *config;
if (!dai || !dai->dai_config) if (!dai || !private || !private->dai_config)
continue; continue;
config = dai->dai_config; config = private->dai_config;
/* /*
* The link DMA channel would be invalidated for running * The link DMA channel would be invalidated for running
* streams but not for streams that were in the PAUSED * streams but not for streams that were in the PAUSED
...@@ -914,18 +918,19 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type) ...@@ -914,18 +918,19 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
struct snd_sof_dai *dai = struct snd_sof_dai *dai =
snd_sof_find_dai(component, (char *)rtd->dai_link->name); snd_sof_find_dai(component, (char *)rtd->dai_link->name);
struct sof_dai_private_data *private = dai->private;
/* use the tplg configured mclk if existed */ /* use the tplg configured mclk if existed */
if (!dai || !dai->dai_config) if (!dai || !private || !private->dai_config)
return 0; return 0;
switch (dai->dai_config->type) { switch (private->dai_config->type) {
case SOF_DAI_INTEL_SSP: case SOF_DAI_INTEL_SSP:
switch (clk_type) { switch (clk_type) {
case SOF_DAI_CLK_INTEL_SSP_MCLK: case SOF_DAI_CLK_INTEL_SSP_MCLK:
return dai->dai_config->ssp.mclk_rate; return private->dai_config->ssp.mclk_rate;
case SOF_DAI_CLK_INTEL_SSP_BCLK: case SOF_DAI_CLK_INTEL_SSP_BCLK:
return dai->dai_config->ssp.bclk_rate; return private->dai_config->ssp.bclk_rate;
default: default:
dev_err(rtd->dev, "fail to get SSP clk %d rate\n", dev_err(rtd->dev, "fail to get SSP clk %d rate\n",
clk_type); clk_type);
...@@ -935,7 +940,7 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type) ...@@ -935,7 +940,7 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
default: default:
/* not yet implemented for platforms other than the above */ /* not yet implemented for platforms other than the above */
dev_err(rtd->dev, "DAI type %d not supported yet!\n", dev_err(rtd->dev, "DAI type %d not supported yet!\n",
dai->dai_config->type); private->dai_config->type);
return -EINVAL; return -EINVAL;
} }
} }
......
...@@ -30,6 +30,18 @@ ...@@ -30,6 +30,18 @@
#define WIDGET_IS_DAI(id) ((id) == snd_soc_dapm_dai_in || (id) == snd_soc_dapm_dai_out) #define WIDGET_IS_DAI(id) ((id) == snd_soc_dapm_dai_in || (id) == snd_soc_dapm_dai_out)
/** struct snd_sof_tuple - Tuple info
* @token: Token ID
* @value: union of a string or a u32 values
*/
struct snd_sof_tuple {
u32 token;
union {
u32 v;
const char *s;
} value;
};
/* PCM stream, mapped to FW component */ /* PCM stream, mapped to FW component */
struct snd_sof_pcm_stream { struct snd_sof_pcm_stream {
u32 comp_id; u32 comp_id;
...@@ -110,8 +122,10 @@ struct snd_sof_widget { ...@@ -110,8 +122,10 @@ struct snd_sof_widget {
struct list_head list; /* list in sdev widget list */ struct list_head list; /* list in sdev widget list */
struct snd_sof_widget *pipe_widget; struct snd_sof_widget *pipe_widget;
/* extended data for UUID components */ const guid_t uuid;
struct sof_ipc_comp_ext comp_ext;
int num_tuples;
struct snd_sof_tuple *tuples;
void *private; /* core does not touch this */ void *private; /* core does not touch this */
}; };
...@@ -134,12 +148,11 @@ struct snd_sof_dai { ...@@ -134,12 +148,11 @@ struct snd_sof_dai {
struct snd_soc_component *scomp; struct snd_soc_component *scomp;
const char *name; const char *name;
struct sof_ipc_comp_dai *comp_dai;
int number_configs; int number_configs;
int current_config; int current_config;
bool configured; /* DAI configured during BE hw_params */ bool configured; /* DAI configured during BE hw_params */
struct sof_ipc_dai_config *dai_config;
struct list_head list; /* list in sdev dai list */ struct list_head list; /* list in sdev dai list */
void *private;
}; };
/* /*
......
...@@ -345,6 +345,18 @@ struct snd_sof_ipc_msg { ...@@ -345,6 +345,18 @@ struct snd_sof_ipc_msg {
bool ipc_complete; bool ipc_complete;
}; };
/* SOF generic IPC data */
struct snd_sof_ipc {
struct snd_sof_dev *sdev;
/* protects messages and the disable flag */
struct mutex tx_mutex;
/* disables further sending of ipc's */
bool disable_ipc_tx;
struct snd_sof_ipc_msg msg;
};
/* /*
* SOF Device Level. * SOF Device Level.
*/ */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment