[alsa-devel] [PATCH 00/17] ASoC: Intel: Skylake: More fixes and updates
Hi all,
This series adds more minor fixes and some enhancements to the driver. Most of the fixes patches are single line count changes
The enhancements are: - optimizing code and using module pin info for unbinding - supporting virtual dsp widgets like switches in topology - add pin formats and supports multiple heterogeneous pins
Hardik T Shah (3): ASoC: Intel: Skylake: Add multiple pin formats ASoC: Intel: Skylake: Update the topology interface structure ASoC: Intel: Skylake: Add support for module GUIDs
Jeeja KP (14): ASoC: Intel: Skylake: Fix to correct check for non DSP widget ASoC: Intel: Skylake: Fix not to ignore return value in be hw_params ASoC: Intel: Skylake: Fix to add 32 bit in update FE params ASoC: Intel: Skylake: Fix to ignore codec_mask check in probe ASoC: Intel: Skylake: Fix to ignore blob check if link type is HDA ASoC: Intel: Skylake: Fix support for multiple pins in a module ASoC: Intel: Skylake: Fix bit depth when querying the NHLT blob ASoC: Intel: Skylake: use module_pin info for unbind ASoC: Intel: Skylake: Add support for virtual dsp widgets ASoC: Intel: Skylake: Fix DSP pipe underrun/overrun issue ASoC: Intel: Skylake: Fix to remove be copier widget power check ASoC: Intel: Skylake: Ignore rate check for DMIC link ASoC: Intel: Skylake: Fix to remove channel_map calculation ASoC: Intel: Skylake: Fix PM behaviour
sound/soc/intel/skylake/skl-messages.c | 189 +++++-------- sound/soc/intel/skylake/skl-nhlt.c | 19 +- sound/soc/intel/skylake/skl-pcm.c | 139 +++++----- sound/soc/intel/skylake/skl-topology.c | 387 ++++++++++++++------------- sound/soc/intel/skylake/skl-topology.h | 35 ++- sound/soc/intel/skylake/skl-tplg-interface.h | 90 +++++-- sound/soc/intel/skylake/skl.c | 63 +++-- sound/soc/intel/skylake/skl.h | 1 - 8 files changed, 483 insertions(+), 440 deletions(-)
From: Jeeja KP jeeja.kp@intel.com
To get the FE copier module, the check to ignore non DSP widgets was wrong. This path corrects the check to ignore non DSP widget.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index a7854c8fc523..98ccd42b8867 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -846,7 +846,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream) w = dai->playback_widget; snd_soc_dapm_widget_for_each_sink_path(w, p) { if (p->connect && p->sink->power && - is_skl_dsp_widget_type(p->sink)) + !is_skl_dsp_widget_type(p->sink)) continue;
if (p->sink->priv) { @@ -859,7 +859,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream) w = dai->capture_widget; snd_soc_dapm_widget_for_each_source_path(w, p) { if (p->connect && p->source->power && - is_skl_dsp_widget_type(p->source)) + !is_skl_dsp_widget_type(p->source)) continue;
if (p->source->priv) {
The patch
ASoC: Intel: Skylake: Fix to correct check for non DSP widget
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 7b83ff3806f9f23cfd0dbe6162ac72e920460cf5 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:44 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to correct check for non DSP widget
To get the FE copier module, the check to ignore non DSP widgets was wrong. This path corrects the check to ignore non DSP widget.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index a7854c8..98ccd42 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -846,7 +846,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream) w = dai->playback_widget; snd_soc_dapm_widget_for_each_sink_path(w, p) { if (p->connect && p->sink->power && - is_skl_dsp_widget_type(p->sink)) + !is_skl_dsp_widget_type(p->sink)) continue;
if (p->sink->priv) { @@ -859,7 +859,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream) w = dai->capture_widget; snd_soc_dapm_widget_for_each_source_path(w, p) { if (p->connect && p->source->power && - is_skl_dsp_widget_type(p->source)) + !is_skl_dsp_widget_type(p->source)) continue;
if (p->source->priv) {
From: Jeeja KP jeeja.kp@intel.com
Return value from skl_tplg_be_update_params() is ignored. But if the blob is null then the hw_params needs to return error. This patch fixes the issue by not ignoring return value from skl_tplg_be_update_params().
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-pcm.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index a2f94ce1679d..1242beac4e46 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -291,9 +291,8 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream, p_params.ch = params_channels(params); p_params.s_freq = params_rate(params); p_params.stream = substream->stream; - skl_tplg_be_update_params(dai, &p_params);
- return 0; + return skl_tplg_be_update_params(dai, &p_params); }
static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, @@ -352,9 +351,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, p_params.stream = substream->stream; p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
- skl_tplg_be_update_params(dai, &p_params); - - return 0; + return skl_tplg_be_update_params(dai, &p_params); }
static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
The patch
ASoC: Intel: Skylake: Fix not to ignore return value in be hw_params
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 68a255813adf564f608ade539bceb994b176bdde Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:45 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix not to ignore return value in be hw_params
Return value from skl_tplg_be_update_params() is ignored. But if the blob is null then the hw_params needs to return error. This patch fixes the issue by not ignoring return value from skl_tplg_be_update_params().
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-pcm.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index a2f94ce..1242bea 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -291,9 +291,8 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream, p_params.ch = params_channels(params); p_params.s_freq = params_rate(params); p_params.stream = substream->stream; - skl_tplg_be_update_params(dai, &p_params);
- return 0; + return skl_tplg_be_update_params(dai, &p_params); }
static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, @@ -352,9 +351,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, p_params.stream = substream->stream; p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
- skl_tplg_be_update_params(dai, &p_params); - - return 0; + return skl_tplg_be_update_params(dai, &p_params); }
static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
From: Jeeja KP jeeja.kp@intel.com
In case of 32 bit, the FE update params returns error as it falls thru to default case. This patch adds 32 bit depth handling in update FE params.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 98ccd42b8867..313a02d8db01 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -809,6 +809,7 @@ int skl_tplg_update_pipe_params(struct device *dev, break;
case SKL_DEPTH_24BIT: + case SKL_DEPTH_32BIT: format->bit_depth = SKL_DEPTH_32BIT; break;
The patch
ASoC: Intel: Skylake: Fix to add 32 bit in update FE params
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 9f891328816ceda2dce3ea25e1e1d375e0c6453d Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:46 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to add 32 bit in update FE params
In case of 32 bit, the FE update params returns error as it falls thru to default case. This patch adds 32 bit depth handling in update FE params.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 98ccd42..313a02d 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -809,6 +809,7 @@ int skl_tplg_update_pipe_params(struct device *dev, break;
case SKL_DEPTH_24BIT: + case SKL_DEPTH_32BIT: format->bit_depth = SKL_DEPTH_32BIT; break;
From: Jeeja KP jeeja.kp@intel.com
We have both I2S and hda codec support in the driver. codec_mask check is relevant only for hda codec and some boards may have only I2S Codec, so removed probe error in case no hda codec is found and update the log to info as it may not be error.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 5319529aedf7..211ef6e2fa21 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -434,8 +434,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
/* codec detection */ if (!bus->codec_mask) { - dev_err(bus->dev, "no codecs found!\n"); - return -ENODEV; + dev_info(bus->dev, "no hda codecs found!\n"); }
return 0;
The patch
ASoC: Intel: Skylake: Fix to ignore codec_mask check in probe
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 17894555d5e2d00e6c6da43342c320c8364d8f0a Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:47 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to ignore codec_mask check in probe
We have both I2S and hda codec support in the driver. codec_mask check is relevant only for hda codec and some boards may have only I2S Codec, so removed probe error in case no hda codec is found and update the log to info as it may not be error.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 5319529..211ef6e2 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -434,8 +434,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
/* codec detection */ if (!bus->codec_mask) { - dev_err(bus->dev, "no codecs found!\n"); - return -ENODEV; + dev_info(bus->dev, "no hda codecs found!\n"); }
return 0;
From: Jeeja KP jeeja.kp@intel.com
If link type is HDA, NHLT blob is null, as NHLT defines non HDA links only. So we should ignore blob query for HDA links.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 313a02d8db01..e11a9e44d064 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -921,6 +921,9 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
memcpy(pipe->p_params, params, sizeof(*params));
+ if (link_type == NHLT_LINK_HDA) + return 0; + /* update the blob based on virtual bus_id*/ cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type, params->s_fmt, params->ch,
The patch
ASoC: Intel: Skylake: Fix to ignore blob check if link type is HDA
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From d38aca5910f665c09e7aeb006fcf19eb3aa789b7 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:48 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to ignore blob check if link type is HDA
If link type is HDA, NHLT blob is null, as NHLT defines non HDA links only. So we should ignore blob query for HDA links.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 313a02d..e11a9e4 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -921,6 +921,9 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
memcpy(pipe->p_params, params, sizeof(*params));
+ if (link_type == NHLT_LINK_HDA) + return 0; + /* update the blob based on virtual bus_id*/ cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type, params->s_fmt, params->ch,
From: Jeeja KP jeeja.kp@intel.com
For supporting multiple dynamic pins, module state check is incorrect. In case of unbind, module state need to be changed to uninit if all pins in the module is is unbind state. To handle module state correctly add pin state and use pin state check to set module state correctly.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-messages.c | 83 ++++++++++++++++++++++------------ sound/soc/intel/skylake/skl-topology.c | 1 + sound/soc/intel/skylake/skl-topology.h | 10 +++- 3 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 50a109503a3f..ee059589e9f0 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -571,10 +571,10 @@ static int skl_get_queue_index(struct skl_module_pin *mpin, * In static, the pin_index is fixed based on module_id and instance id */ static int skl_alloc_queue(struct skl_module_pin *mpin, - struct skl_module_inst_id id, int max) + struct skl_module_cfg *tgt_cfg, int max) { int i; - + struct skl_module_inst_id id = tgt_cfg->id; /* * if pin in dynamic, find first free pin * otherwise find match module and instance id pin as topology will @@ -583,16 +583,23 @@ static int skl_alloc_queue(struct skl_module_pin *mpin, */ for (i = 0; i < max; i++) { if (mpin[i].is_dynamic) { - if (!mpin[i].in_use) { + if (!mpin[i].in_use && + mpin[i].pin_state == SKL_PIN_UNBIND) { + mpin[i].in_use = true; mpin[i].id.module_id = id.module_id; mpin[i].id.instance_id = id.instance_id; + mpin[i].tgt_mcfg = tgt_cfg; return i; } } else { if (mpin[i].id.module_id == id.module_id && - mpin[i].id.instance_id == id.instance_id) + mpin[i].id.instance_id == id.instance_id && + mpin[i].pin_state == SKL_PIN_UNBIND) { + + mpin[i].tgt_mcfg = tgt_cfg; return i; + } } }
@@ -606,6 +613,28 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index) mpin[q_index].id.module_id = 0; mpin[q_index].id.instance_id = 0; } + mpin[q_index].pin_state = SKL_PIN_UNBIND; + mpin[q_index].tgt_mcfg = NULL; +} + +/* Module state will be set to unint, if all the out pin state is UNBIND */ + +static void skl_clear_module_state(struct skl_module_pin *mpin, int max, + struct skl_module_cfg *mcfg) +{ + int i; + bool found = false; + + for (i = 0; i < max; i++) { + if (mpin[i].pin_state == SKL_PIN_UNBIND) + continue; + found = true; + break; + } + + if (!found) + mcfg->m_state = SKL_MODULE_UNINIT; + return; }
/* @@ -682,37 +711,30 @@ int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; - int src_index, dst_index; + int src_index, dst_index, src_pin_state, dst_pin_state;
skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
- if (src_mcfg->m_state != SKL_MODULE_BIND_DONE) - return 0; - - /* - * if intra module unbind, check if both modules are BIND, - * then send unbind - */ - if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) && - dst_mcfg->m_state != SKL_MODULE_BIND_DONE) - return 0; - else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE && - dst_mcfg->m_state < SKL_MODULE_INIT_DONE) - return 0; - /* get src queue index */ src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); if (src_index < 0) return -EINVAL;
- msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; + msg.src_queue = src_index;
/* get dst queue index */ dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); if (dst_index < 0) return -EINVAL;
- msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; + msg.dst_queue = dst_index; + + src_pin_state = src_mcfg->m_out_pin[src_index].pin_state; + dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state; + + if (src_pin_state != SKL_PIN_BIND_DONE || + dst_pin_state != SKL_PIN_BIND_DONE) + return 0;
msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.instance_id; @@ -722,10 +744,15 @@ int skl_unbind_modules(struct skl_sst *ctx,
ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { - src_mcfg->m_state = SKL_MODULE_UNINIT; /* free queue only if unbind is success */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); + + /* + * check only if src module bind state, bind is + * always from src -> sink + */ + skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg); }
return ret; @@ -744,8 +771,6 @@ int skl_bind_modules(struct skl_sst *ctx, { int ret; struct skl_ipc_bind_unbind_msg msg; - struct skl_module_inst_id src_id = src_mcfg->id; - struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; int src_index, dst_index; @@ -756,18 +781,18 @@ int skl_bind_modules(struct skl_sst *ctx, dst_mcfg->m_state < SKL_MODULE_INIT_DONE) return 0;
- src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_id, out_max); + src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); if (src_index < 0) return -EINVAL;
- msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; - dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_id, in_max); + msg.src_queue = src_index; + dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); if (dst_index < 0) { skl_free_queue(src_mcfg->m_out_pin, src_index); return -EINVAL; }
- msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; + msg.dst_queue = dst_index;
dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", msg.src_queue, msg.dst_queue); @@ -782,6 +807,8 @@ int skl_bind_modules(struct skl_sst *ctx,
if (!ret) { src_mcfg->m_state = SKL_MODULE_BIND_DONE; + src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; + dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; } else { /* error case , if IPC fails, clear the queue index */ skl_free_queue(src_mcfg->m_out_pin, src_index); diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index e11a9e44d064..e8258d4807ff 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1049,6 +1049,7 @@ static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin, m_pin[i].id.instance_id = dfw_pin[i].instance_id; m_pin[i].in_use = false; m_pin[i].is_dynamic = is_dynamic; + m_pin[i].pin_state = SKL_PIN_UNBIND; } }
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 76053a8de41c..cd8768308f29 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -180,16 +180,24 @@ struct skl_module_fmt { u32 ch_cfg; };
+struct skl_module_cfg; + struct skl_module_inst_id { u32 module_id; u32 instance_id; };
+enum skl_module_pin_state { + SKL_PIN_UNBIND = 0, + SKL_PIN_BIND_DONE = 1, +}; + struct skl_module_pin { struct skl_module_inst_id id; - u8 pin_index; bool is_dynamic; bool in_use; + enum skl_module_pin_state pin_state; + struct skl_module_cfg *tgt_mcfg; };
struct skl_specific_cfg {
The patch
ASoC: Intel: Skylake: Fix support for multiple pins in a module
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 2e01daa7aba46c55faad9d5f0d262d45f80ddfce Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:49 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix support for multiple pins in a module
For supporting multiple dynamic pins, module state check is incorrect. In case of unbind, module state need to be changed to uninit if all pins in the module is is unbind state. To handle module state correctly add pin state and use pin state check to set module state correctly.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-messages.c | 83 ++++++++++++++++++++++------------ sound/soc/intel/skylake/skl-topology.c | 1 + sound/soc/intel/skylake/skl-topology.h | 10 +++- 3 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 50a1095..ee05958 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -571,10 +571,10 @@ static int skl_get_queue_index(struct skl_module_pin *mpin, * In static, the pin_index is fixed based on module_id and instance id */ static int skl_alloc_queue(struct skl_module_pin *mpin, - struct skl_module_inst_id id, int max) + struct skl_module_cfg *tgt_cfg, int max) { int i; - + struct skl_module_inst_id id = tgt_cfg->id; /* * if pin in dynamic, find first free pin * otherwise find match module and instance id pin as topology will @@ -583,16 +583,23 @@ static int skl_alloc_queue(struct skl_module_pin *mpin, */ for (i = 0; i < max; i++) { if (mpin[i].is_dynamic) { - if (!mpin[i].in_use) { + if (!mpin[i].in_use && + mpin[i].pin_state == SKL_PIN_UNBIND) { + mpin[i].in_use = true; mpin[i].id.module_id = id.module_id; mpin[i].id.instance_id = id.instance_id; + mpin[i].tgt_mcfg = tgt_cfg; return i; } } else { if (mpin[i].id.module_id == id.module_id && - mpin[i].id.instance_id == id.instance_id) + mpin[i].id.instance_id == id.instance_id && + mpin[i].pin_state == SKL_PIN_UNBIND) { + + mpin[i].tgt_mcfg = tgt_cfg; return i; + } } }
@@ -606,6 +613,28 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index) mpin[q_index].id.module_id = 0; mpin[q_index].id.instance_id = 0; } + mpin[q_index].pin_state = SKL_PIN_UNBIND; + mpin[q_index].tgt_mcfg = NULL; +} + +/* Module state will be set to unint, if all the out pin state is UNBIND */ + +static void skl_clear_module_state(struct skl_module_pin *mpin, int max, + struct skl_module_cfg *mcfg) +{ + int i; + bool found = false; + + for (i = 0; i < max; i++) { + if (mpin[i].pin_state == SKL_PIN_UNBIND) + continue; + found = true; + break; + } + + if (!found) + mcfg->m_state = SKL_MODULE_UNINIT; + return; }
/* @@ -682,37 +711,30 @@ int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; - int src_index, dst_index; + int src_index, dst_index, src_pin_state, dst_pin_state;
skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
- if (src_mcfg->m_state != SKL_MODULE_BIND_DONE) - return 0; - - /* - * if intra module unbind, check if both modules are BIND, - * then send unbind - */ - if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) && - dst_mcfg->m_state != SKL_MODULE_BIND_DONE) - return 0; - else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE && - dst_mcfg->m_state < SKL_MODULE_INIT_DONE) - return 0; - /* get src queue index */ src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); if (src_index < 0) return -EINVAL;
- msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; + msg.src_queue = src_index;
/* get dst queue index */ dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); if (dst_index < 0) return -EINVAL;
- msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; + msg.dst_queue = dst_index; + + src_pin_state = src_mcfg->m_out_pin[src_index].pin_state; + dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state; + + if (src_pin_state != SKL_PIN_BIND_DONE || + dst_pin_state != SKL_PIN_BIND_DONE) + return 0;
msg.module_id = src_mcfg->id.module_id; msg.instance_id = src_mcfg->id.instance_id; @@ -722,10 +744,15 @@ int skl_unbind_modules(struct skl_sst *ctx,
ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); if (!ret) { - src_mcfg->m_state = SKL_MODULE_UNINIT; /* free queue only if unbind is success */ skl_free_queue(src_mcfg->m_out_pin, src_index); skl_free_queue(dst_mcfg->m_in_pin, dst_index); + + /* + * check only if src module bind state, bind is + * always from src -> sink + */ + skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg); }
return ret; @@ -744,8 +771,6 @@ int skl_bind_modules(struct skl_sst *ctx, { int ret; struct skl_ipc_bind_unbind_msg msg; - struct skl_module_inst_id src_id = src_mcfg->id; - struct skl_module_inst_id dst_id = dst_mcfg->id; int in_max = dst_mcfg->max_in_queue; int out_max = src_mcfg->max_out_queue; int src_index, dst_index; @@ -756,18 +781,18 @@ int skl_bind_modules(struct skl_sst *ctx, dst_mcfg->m_state < SKL_MODULE_INIT_DONE) return 0;
- src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_id, out_max); + src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); if (src_index < 0) return -EINVAL;
- msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; - dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_id, in_max); + msg.src_queue = src_index; + dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); if (dst_index < 0) { skl_free_queue(src_mcfg->m_out_pin, src_index); return -EINVAL; }
- msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; + msg.dst_queue = dst_index;
dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", msg.src_queue, msg.dst_queue); @@ -782,6 +807,8 @@ int skl_bind_modules(struct skl_sst *ctx,
if (!ret) { src_mcfg->m_state = SKL_MODULE_BIND_DONE; + src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; + dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; } else { /* error case , if IPC fails, clear the queue index */ skl_free_queue(src_mcfg->m_out_pin, src_index); diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index e11a9e4..e8258d4 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1049,6 +1049,7 @@ static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin, m_pin[i].id.instance_id = dfw_pin[i].instance_id; m_pin[i].in_use = false; m_pin[i].is_dynamic = is_dynamic; + m_pin[i].pin_state = SKL_PIN_UNBIND; } }
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 76053a8..cd87683 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -180,16 +180,24 @@ struct skl_module_fmt { u32 ch_cfg; };
+struct skl_module_cfg; + struct skl_module_inst_id { u32 module_id; u32 instance_id; };
+enum skl_module_pin_state { + SKL_PIN_UNBIND = 0, + SKL_PIN_BIND_DONE = 1, +}; + struct skl_module_pin { struct skl_module_inst_id id; - u8 pin_index; bool is_dynamic; bool in_use; + enum skl_module_pin_state pin_state; + struct skl_module_cfg *tgt_mcfg; };
struct skl_specific_cfg {
From: Jeeja KP jeeja.kp@intel.com
Bps calculation is not correct as this needs to be based on valid bit depth. 16 bit fmt bit depth is 16 bit and for 24 and 32 bit as it is container size This patch fixes the bps.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-nhlt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index b0c7bd113aac..3ff22eba5875 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c @@ -115,7 +115,7 @@ struct nhlt_specific_cfg struct device *dev = bus->dev; struct nhlt_specific_cfg *sp_config; struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; - u16 bps = num_ch * s_fmt; + u16 bps = (s_fmt == 16) ? 16 : 32; u8 j;
dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps);
The patch
ASoC: Intel: Skylake: Fix bit depth when querying the NHLT blob
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 4dfdd449760654cdedda2f40c23d7f3cb864b02a Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:50 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix bit depth when querying the NHLT blob
Bps calculation is not correct as this needs to be based on valid bit depth. 16 bit fmt bit depth is 16 bit and for 24 and 32 bit as it is container size This patch fixes the bps.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-nhlt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index b0c7bd1..3ff22eb 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c @@ -115,7 +115,7 @@ struct nhlt_specific_cfg struct device *dev = bus->dev; struct nhlt_specific_cfg *sp_config; struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; - u16 bps = num_ch * s_fmt; + u16 bps = (s_fmt == 16) ? 16 : 32; u8 j;
dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps);
From: Jeeja KP jeeja.kp@intel.com
in_pin and out_pin list for a module has the information about the module that are bound together. So we can directly look at pin information of module for binding and unbind.
As a result the preinitialized dapm_path_last we had is removed and code and memory optimzed.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-pcm.c | 1 - sound/soc/intel/skylake/skl-topology.c | 108 +++++++++++---------------------- sound/soc/intel/skylake/skl-topology.h | 5 -- sound/soc/intel/skylake/skl.h | 1 - 4 files changed, 34 insertions(+), 81 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1242beac4e46..1a9cd00c0b0a 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -938,7 +938,6 @@ int skl_platform_register(struct device *dev) struct skl *skl = ebus_to_skl(ebus);
INIT_LIST_HEAD(&skl->ppl_list); - INIT_LIST_HEAD(&skl->dapm_path_list);
ret = snd_soc_register_platform(dev, &skl_platform_drv); if (ret) { diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index e8258d4807ff..abbf8e7eb3e7 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -411,7 +411,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, struct skl *skl) { struct snd_soc_dapm_path *p; - struct skl_dapm_path_list *path_list; struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; @@ -455,16 +454,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret; } - - path_list = kzalloc( - sizeof(struct skl_dapm_path_list), - GFP_KERNEL); - if (path_list == NULL) - return -ENOMEM; - - /* Add connected path to one global list */ - path_list->dapm_path = p; - list_add_tail(&path_list->node, &skl->dapm_path_list); break; } } @@ -552,54 +541,37 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, struct skl *skl) { - struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; - int ret = 0, path_found = 0; - struct skl_dapm_path_list *path_list, *tmp_list; + int ret = 0, i; struct skl_sst *ctx = skl->skl_sst;
- sink = w; - sink_mconfig = sink->priv; + sink_mconfig = w->priv;
/* Stop the pipe */ ret = skl_stop_pipe(ctx, sink_mconfig->pipe); if (ret) return ret;
- /* - * This list, dapm_path_list handling here does not need any locks - * as we are under dapm lock while handling widget events. - * List can be manipulated safely only under dapm widgets handler - * routines - */ - list_for_each_entry_safe(path_list, tmp_list, - &skl->dapm_path_list, node) { - if (path_list->dapm_path->sink == sink) { - dev_dbg(ctx->dev, "Path found = %s\n", - path_list->dapm_path->name); - source = path_list->dapm_path->source; - src_mconfig = source->priv; - path_found = 1; + for (i = 0; i < sink_mconfig->max_in_queue; i++) { + if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) { + src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; + if (!src_mconfig) + continue; + /* + * If path_found == 1, that means pmd for source + * pipe has not occurred, source is connected to + * some other sink. so its responsibility of sink + * to unbind itself from source. + */ + ret = skl_stop_pipe(ctx, src_mconfig->pipe); + if (ret < 0) + return ret;
- list_del(&path_list->node); - kfree(path_list); - break; + ret = skl_unbind_modules(ctx, + src_mconfig, sink_mconfig); } }
- /* - * If path_found == 1, that means pmd for source pipe has - * not occurred, source is connected to some other sink. - * so its responsibility of sink to unbind itself from source. - */ - if (path_found) { - ret = skl_stop_pipe(ctx, src_mconfig->pipe); - if (ret < 0) - return ret; - - ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); - } - return ret; }
@@ -653,14 +625,11 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, struct skl *skl) { - struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; - int ret = 0, path_found = 0; - struct skl_dapm_path_list *path_list, *tmp_path_list; + int ret = 0, i; struct skl_sst *ctx = skl->skl_sst;
- source = w; - src_mconfig = source->priv; + src_mconfig = w->priv;
skl_tplg_free_pipe_mcps(skl, src_mconfig); /* Stop the pipe since this is a mixin module */ @@ -668,32 +637,23 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret;
- list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) { - if (path_list->dapm_path->source == source) { - dev_dbg(ctx->dev, "Path found = %s\n", - path_list->dapm_path->name); - sink = path_list->dapm_path->sink; - sink_mconfig = sink->priv; - path_found = 1; - - list_del(&path_list->node); - kfree(path_list); - break; + for (i = 0; i < src_mconfig->max_out_queue; i++) { + if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) { + sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg; + if (!sink_mconfig) + continue; + /* + * This is a connecter and if path is found that means + * unbind between source and sink has not happened yet + */ + ret = skl_stop_pipe(ctx, sink_mconfig->pipe); + if (ret < 0) + return ret; + ret = skl_unbind_modules(ctx, src_mconfig, + sink_mconfig); } }
- /* - * This is a connector and if path is found that means - * unbind between source and sink has not happened yet - */ - if (path_found) { - ret = skl_stop_pipe(ctx, src_mconfig->pipe); - if (ret < 0) - return ret; - - ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); - } - return ret; }
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index cd8768308f29..1b35cb6c397a 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -280,11 +280,6 @@ struct skl_pipeline { struct list_head node; };
-struct skl_dapm_path_list { - struct snd_soc_dapm_path *dapm_path; - struct list_head node; -}; - static inline struct skl *get_skl_ctx(struct device *dev) { struct hdac_ext_bus *ebus = dev_get_drvdata(dev); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index dd2e79ae45a8..f803ebb10605 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -67,7 +67,6 @@ struct skl {
struct skl_dsp_resource resource; struct list_head ppl_list; - struct list_head dapm_path_list; };
#define skl_to_ebus(s) (&(s)->ebus)
The patch
ASoC: Intel: Skylake: use module_pin info for unbind
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 3cda69f8bdb726a3b253369f20418e29d92829a3 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:51 +0900 Subject: [PATCH] ASoC: Intel: Skylake: use module_pin info for unbind
in_pin and out_pin list for a module has the information about the module that are bound together. So we can directly look at pin information of module for binding and unbind.
As a result the preinitialized dapm_path_last we had is removed and code and memory optimzed.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-pcm.c | 1 - sound/soc/intel/skylake/skl-topology.c | 108 +++++++++++---------------------- sound/soc/intel/skylake/skl-topology.h | 5 -- sound/soc/intel/skylake/skl.h | 1 - 4 files changed, 34 insertions(+), 81 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1242bea..1a9cd00 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -938,7 +938,6 @@ int skl_platform_register(struct device *dev) struct skl *skl = ebus_to_skl(ebus);
INIT_LIST_HEAD(&skl->ppl_list); - INIT_LIST_HEAD(&skl->dapm_path_list);
ret = snd_soc_register_platform(dev, &skl_platform_drv); if (ret) { diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index e8258d4..abbf8e7 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -411,7 +411,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, struct skl *skl) { struct snd_soc_dapm_path *p; - struct skl_dapm_path_list *path_list; struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; @@ -455,16 +454,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret; } - - path_list = kzalloc( - sizeof(struct skl_dapm_path_list), - GFP_KERNEL); - if (path_list == NULL) - return -ENOMEM; - - /* Add connected path to one global list */ - path_list->dapm_path = p; - list_add_tail(&path_list->node, &skl->dapm_path_list); break; } } @@ -552,54 +541,37 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, struct skl *skl) { - struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; - int ret = 0, path_found = 0; - struct skl_dapm_path_list *path_list, *tmp_list; + int ret = 0, i; struct skl_sst *ctx = skl->skl_sst;
- sink = w; - sink_mconfig = sink->priv; + sink_mconfig = w->priv;
/* Stop the pipe */ ret = skl_stop_pipe(ctx, sink_mconfig->pipe); if (ret) return ret;
- /* - * This list, dapm_path_list handling here does not need any locks - * as we are under dapm lock while handling widget events. - * List can be manipulated safely only under dapm widgets handler - * routines - */ - list_for_each_entry_safe(path_list, tmp_list, - &skl->dapm_path_list, node) { - if (path_list->dapm_path->sink == sink) { - dev_dbg(ctx->dev, "Path found = %s\n", - path_list->dapm_path->name); - source = path_list->dapm_path->source; - src_mconfig = source->priv; - path_found = 1; + for (i = 0; i < sink_mconfig->max_in_queue; i++) { + if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) { + src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; + if (!src_mconfig) + continue; + /* + * If path_found == 1, that means pmd for source + * pipe has not occurred, source is connected to + * some other sink. so its responsibility of sink + * to unbind itself from source. + */ + ret = skl_stop_pipe(ctx, src_mconfig->pipe); + if (ret < 0) + return ret;
- list_del(&path_list->node); - kfree(path_list); - break; + ret = skl_unbind_modules(ctx, + src_mconfig, sink_mconfig); } }
- /* - * If path_found == 1, that means pmd for source pipe has - * not occurred, source is connected to some other sink. - * so its responsibility of sink to unbind itself from source. - */ - if (path_found) { - ret = skl_stop_pipe(ctx, src_mconfig->pipe); - if (ret < 0) - return ret; - - ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); - } - return ret; }
@@ -653,14 +625,11 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, struct skl *skl) { - struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; - int ret = 0, path_found = 0; - struct skl_dapm_path_list *path_list, *tmp_path_list; + int ret = 0, i; struct skl_sst *ctx = skl->skl_sst;
- source = w; - src_mconfig = source->priv; + src_mconfig = w->priv;
skl_tplg_free_pipe_mcps(skl, src_mconfig); /* Stop the pipe since this is a mixin module */ @@ -668,32 +637,23 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret;
- list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) { - if (path_list->dapm_path->source == source) { - dev_dbg(ctx->dev, "Path found = %s\n", - path_list->dapm_path->name); - sink = path_list->dapm_path->sink; - sink_mconfig = sink->priv; - path_found = 1; - - list_del(&path_list->node); - kfree(path_list); - break; + for (i = 0; i < src_mconfig->max_out_queue; i++) { + if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) { + sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg; + if (!sink_mconfig) + continue; + /* + * This is a connecter and if path is found that means + * unbind between source and sink has not happened yet + */ + ret = skl_stop_pipe(ctx, sink_mconfig->pipe); + if (ret < 0) + return ret; + ret = skl_unbind_modules(ctx, src_mconfig, + sink_mconfig); } }
- /* - * This is a connector and if path is found that means - * unbind between source and sink has not happened yet - */ - if (path_found) { - ret = skl_stop_pipe(ctx, src_mconfig->pipe); - if (ret < 0) - return ret; - - ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); - } - return ret; }
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index cd87683..1b35cb6 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -280,11 +280,6 @@ struct skl_pipeline { struct list_head node; };
-struct skl_dapm_path_list { - struct snd_soc_dapm_path *dapm_path; - struct list_head node; -}; - static inline struct skl *get_skl_ctx(struct device *dev) { struct hdac_ext_bus *ebus = dev_get_drvdata(dev); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index dd2e79a..f803ebb 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -67,7 +67,6 @@ struct skl {
struct skl_dsp_resource resource; struct list_head ppl_list; - struct list_head dapm_path_list; };
#define skl_to_ebus(s) (&(s)->ebus)
From: Jeeja KP jeeja.kp@intel.com
In SKL topology routes, some paths can be connected by a widget which are not a DSP FW widget and virtual with respect to firmware. In these case when module has to bind, then the virtual DSP modules needs to skipped till a actual DSP module is found which connects the pipelines.
So we need to walk the graph and find a widget which is real in nature. This patch adds that support and splits skl_tplg_pga_dapm_pre_pmu_event() fn with parsing code to skl_tplg_bind_sinks() fn and call that recursively as well as while parsing
The patch moves code a bit while splitting so diffstat doesn't tell real picture
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 133 ++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 50 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index abbf8e7eb3e7..0c6e7833e652 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -397,40 +397,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return 0; }
-/* - * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA - * we need to do following: - * - Bind to sink pipeline - * Since the sink pipes can be running and we don't get mixer event on - * connect for already running mixer, we need to find the sink pipes - * here and bind to them. This way dynamic connect works. - * - Start sink pipeline, if not running - * - Then run current pipe - */ -static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, - struct skl *skl) +static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, + struct skl *skl, + struct skl_module_cfg *src_mconfig) { struct snd_soc_dapm_path *p; - struct snd_soc_dapm_widget *source, *sink; - struct skl_module_cfg *src_mconfig, *sink_mconfig; + struct snd_soc_dapm_widget *sink = NULL; + struct skl_module_cfg *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; - int ret = 0; - - source = w; - src_mconfig = source->priv; + int ret;
- /* - * find which sink it is connected to, bind with the sink, - * if sink is not started, start sink pipe first, then start - * this pipe - */ - snd_soc_dapm_widget_for_each_source_path(w, p) { + snd_soc_dapm_widget_for_each_sink_path(w, p) { if (!p->connect) continue;
dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
+ sink = p->sink; /* * here we will check widgets in sink pipelines, so that * can be any widgets type and we are only interested if @@ -440,7 +424,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, is_skl_dsp_widget_type(p->sink)) {
sink = p->sink; - src_mconfig = source->priv; sink_mconfig = sink->priv;
/* Bind source to sink, mixin is always source */ @@ -454,10 +437,43 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret; } - break; } }
+ if (!sink) + return skl_tplg_bind_sinks(sink, skl, src_mconfig); + + return 0; +} + +/* + * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA + * we need to do following: + * - Bind to sink pipeline + * Since the sink pipes can be running and we don't get mixer event on + * connect for already running mixer, we need to find the sink pipes + * here and bind to them. This way dynamic connect works. + * - Start sink pipeline, if not running + * - Then run current pipe + */ +static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, + struct skl *skl) +{ + struct skl_module_cfg *src_mconfig; + struct skl_sst *ctx = skl->skl_sst; + int ret = 0; + + src_mconfig = w->priv; + + /* + * find which sink it is connected to, bind with the sink, + * if sink is not started, start sink pipe first, then start + * this pipe + */ + ret = skl_tplg_bind_sinks(w, skl, src_mconfig); + if (ret) + return ret; + /* Start source pipe last after starting all sinks */ ret = skl_run_pipe(ctx, src_mconfig->pipe); if (ret) @@ -466,6 +482,38 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return 0; }
+static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( + struct snd_soc_dapm_widget *w, struct skl *skl) +{ + struct snd_soc_dapm_path *p; + struct snd_soc_dapm_widget *src_w = NULL; + struct skl_sst *ctx = skl->skl_sst; + + snd_soc_dapm_widget_for_each_source_path(w, p) { + src_w = p->source; + if (!p->connect) + continue; + + dev_dbg(ctx->dev, "sink widget=%s\n", w->name); + dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); + + /* + * here we will check widgets in sink pipelines, so that can + * be any widgets type and we are only interested if they are + * ones used for SKL so check that first + */ + if ((p->source->priv != NULL) && + is_skl_dsp_widget_type(p->source)) { + return p->source; + } + } + + if (src_w != NULL) + return skl_get_src_dsp_widget(src_w, skl); + + return NULL; +} + /* * in the Post-PMU event of mixer we need to do following: * - Check if this pipe is running @@ -479,7 +527,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, struct skl *skl) { int ret = 0; - struct snd_soc_dapm_path *p; struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; @@ -493,32 +540,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, * one more sink before this sink got connected, Since source is * started, bind this sink to source and start this pipe. */ - snd_soc_dapm_widget_for_each_sink_path(w, p) { - if (!p->connect) - continue; - - dev_dbg(ctx->dev, "sink widget=%s\n", w->name); - dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); + source = skl_get_src_dsp_widget(w, skl); + if (source != NULL) { + src_mconfig = source->priv; + sink_mconfig = sink->priv; + src_pipe_started = 1;
/* - * here we will check widgets in sink pipelines, so that - * can be any widgets type and we are only interested if - * they are ones used for SKL so check that first + * check pipe state, then no need to bind or start the + * pipe */ - if ((p->source->priv != NULL) && - is_skl_dsp_widget_type(p->source)) { - source = p->source; - src_mconfig = source->priv; - sink_mconfig = sink->priv; - src_pipe_started = 1; - - /* - * check pipe state, then no need to bind or start - * the pipe - */ - if (src_mconfig->pipe->state != SKL_PIPE_STARTED) - src_pipe_started = 0; - } + if (src_mconfig->pipe->state != SKL_PIPE_STARTED) + src_pipe_started = 0; }
if (src_pipe_started) {
The patch
ASoC: Intel: Skylake: Add support for virtual dsp widgets
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 9a3b9dc636b03a01c9f1b7ce699242983a32d579 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:52 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Add support for virtual dsp widgets
In SKL topology routes, some paths can be connected by a widget which are not a DSP FW widget and virtual with respect to firmware. In these case when module has to bind, then the virtual DSP modules needs to skipped till a actual DSP module is found which connects the pipelines.
So we need to walk the graph and find a widget which is real in nature. This patch adds that support and splits skl_tplg_pga_dapm_pre_pmu_event() fn with parsing code to skl_tplg_bind_sinks() fn and call that recursively as well as while parsing
The patch moves code a bit while splitting so diffstat doesn't tell real picture
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 133 ++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 50 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index abbf8e7..0c6e783 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -397,40 +397,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return 0; }
-/* - * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA - * we need to do following: - * - Bind to sink pipeline - * Since the sink pipes can be running and we don't get mixer event on - * connect for already running mixer, we need to find the sink pipes - * here and bind to them. This way dynamic connect works. - * - Start sink pipeline, if not running - * - Then run current pipe - */ -static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, - struct skl *skl) +static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, + struct skl *skl, + struct skl_module_cfg *src_mconfig) { struct snd_soc_dapm_path *p; - struct snd_soc_dapm_widget *source, *sink; - struct skl_module_cfg *src_mconfig, *sink_mconfig; + struct snd_soc_dapm_widget *sink = NULL; + struct skl_module_cfg *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; - int ret = 0; - - source = w; - src_mconfig = source->priv; + int ret;
- /* - * find which sink it is connected to, bind with the sink, - * if sink is not started, start sink pipe first, then start - * this pipe - */ - snd_soc_dapm_widget_for_each_source_path(w, p) { + snd_soc_dapm_widget_for_each_sink_path(w, p) { if (!p->connect) continue;
dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
+ sink = p->sink; /* * here we will check widgets in sink pipelines, so that * can be any widgets type and we are only interested if @@ -440,7 +424,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, is_skl_dsp_widget_type(p->sink)) {
sink = p->sink; - src_mconfig = source->priv; sink_mconfig = sink->priv;
/* Bind source to sink, mixin is always source */ @@ -454,10 +437,43 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret; } - break; } }
+ if (!sink) + return skl_tplg_bind_sinks(sink, skl, src_mconfig); + + return 0; +} + +/* + * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA + * we need to do following: + * - Bind to sink pipeline + * Since the sink pipes can be running and we don't get mixer event on + * connect for already running mixer, we need to find the sink pipes + * here and bind to them. This way dynamic connect works. + * - Start sink pipeline, if not running + * - Then run current pipe + */ +static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, + struct skl *skl) +{ + struct skl_module_cfg *src_mconfig; + struct skl_sst *ctx = skl->skl_sst; + int ret = 0; + + src_mconfig = w->priv; + + /* + * find which sink it is connected to, bind with the sink, + * if sink is not started, start sink pipe first, then start + * this pipe + */ + ret = skl_tplg_bind_sinks(w, skl, src_mconfig); + if (ret) + return ret; + /* Start source pipe last after starting all sinks */ ret = skl_run_pipe(ctx, src_mconfig->pipe); if (ret) @@ -466,6 +482,38 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return 0; }
+static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( + struct snd_soc_dapm_widget *w, struct skl *skl) +{ + struct snd_soc_dapm_path *p; + struct snd_soc_dapm_widget *src_w = NULL; + struct skl_sst *ctx = skl->skl_sst; + + snd_soc_dapm_widget_for_each_source_path(w, p) { + src_w = p->source; + if (!p->connect) + continue; + + dev_dbg(ctx->dev, "sink widget=%s\n", w->name); + dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); + + /* + * here we will check widgets in sink pipelines, so that can + * be any widgets type and we are only interested if they are + * ones used for SKL so check that first + */ + if ((p->source->priv != NULL) && + is_skl_dsp_widget_type(p->source)) { + return p->source; + } + } + + if (src_w != NULL) + return skl_get_src_dsp_widget(src_w, skl); + + return NULL; +} + /* * in the Post-PMU event of mixer we need to do following: * - Check if this pipe is running @@ -479,7 +527,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, struct skl *skl) { int ret = 0; - struct snd_soc_dapm_path *p; struct snd_soc_dapm_widget *source, *sink; struct skl_module_cfg *src_mconfig, *sink_mconfig; struct skl_sst *ctx = skl->skl_sst; @@ -493,32 +540,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, * one more sink before this sink got connected, Since source is * started, bind this sink to source and start this pipe. */ - snd_soc_dapm_widget_for_each_sink_path(w, p) { - if (!p->connect) - continue; - - dev_dbg(ctx->dev, "sink widget=%s\n", w->name); - dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); + source = skl_get_src_dsp_widget(w, skl); + if (source != NULL) { + src_mconfig = source->priv; + sink_mconfig = sink->priv; + src_pipe_started = 1;
/* - * here we will check widgets in sink pipelines, so that - * can be any widgets type and we are only interested if - * they are ones used for SKL so check that first + * check pipe state, then no need to bind or start the + * pipe */ - if ((p->source->priv != NULL) && - is_skl_dsp_widget_type(p->source)) { - source = p->source; - src_mconfig = source->priv; - sink_mconfig = sink->priv; - src_pipe_started = 1; - - /* - * check pipe state, then no need to bind or start - * the pipe - */ - if (src_mconfig->pipe->state != SKL_PIPE_STARTED) - src_pipe_started = 0; - } + if (src_mconfig->pipe->state != SKL_PIPE_STARTED) + src_pipe_started = 0; }
if (src_pipe_started) {
From: Jeeja KP jeeja.kp@intel.com
While rigourous testing of SKL drivers, we noticed underuns and overuns and on debug realized that we need to change driver handling of FE pipe startup and shutdown
We need to start DMA and then run pipe together and not split these up. Similarly while stopping we should stop pipe and then DMA in a sequence.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-pcm.c | 133 +++++++++++++++++++-------------- sound/soc/intel/skylake/skl-topology.c | 13 ++-- 2 files changed, 85 insertions(+), 61 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1a9cd00c0b0a..2517ec576ffc 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -295,29 +295,101 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream, return skl_tplg_be_update_params(dai, &p_params); }
+static int skl_decoupled_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_ext_stream *stream; + int start; + unsigned long cookie; + struct hdac_stream *hstr; + + stream = get_hdac_ext_stream(substream); + hstr = hdac_stream(stream); + + if (!hstr->prepared) + return -EPIPE; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + start = 1; + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + start = 0; + break; + + default: + return -EINVAL; + } + + spin_lock_irqsave(&bus->reg_lock, cookie); + + if (start) { + snd_hdac_stream_start(hdac_stream(stream), true); + snd_hdac_stream_timecounter_init(hstr, 0); + } else { + snd_hdac_stream_stop(hdac_stream(stream)); + } + + spin_unlock_irqrestore(&bus->reg_lock, cookie); + + return 0; +} + static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct skl *skl = get_skl_ctx(dai->dev); struct skl_sst *ctx = skl->skl_sst; struct skl_module_cfg *mconfig; + int ret;
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); if (!mconfig) return -EIO;
switch (cmd) { + case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: + /* + * Start HOST DMA and Start FE Pipe.This is to make sure that + * there are no underrun/overrun in the case when the FE + * pipeline is started but there is a delay in starting the + * DMA channel on the host. + */ + ret = skl_decoupled_trigger(substream, cmd); + if (ret < 0) + return ret; return skl_run_pipe(ctx, mconfig->pipe); + break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - return skl_stop_pipe(ctx, mconfig->pipe); + case SNDRV_PCM_TRIGGER_STOP: + /* + * Stop FE Pipe first and stop DMA. This is to make sure that + * there are no underrun/overrun in the case if there is a delay + * between the two operations. + */ + ret = skl_stop_pipe(ctx, mconfig->pipe); + if (ret < 0) + return ret; + + ret = skl_decoupled_trigger(substream, cmd); + break;
default: - return 0; + return -EINVAL; } + + return 0; }
static int skl_link_hw_params(struct snd_pcm_substream *substream, @@ -685,66 +757,15 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream, return 0; }
-static int skl_decoupled_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct hdac_ext_bus *ebus = get_bus_ctx(substream); - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct hdac_ext_stream *stream; - int start; - unsigned long cookie; - struct hdac_stream *hstr; - - dev_dbg(bus->dev, "In %s cmd=%d streamname=%s\n", __func__, cmd, cpu_dai->name); - - stream = get_hdac_ext_stream(substream); - hstr = hdac_stream(stream); - - if (!hstr->prepared) - return -EPIPE; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - start = 1; - break; - - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - start = 0; - break; - - default: - return -EINVAL; - } - - spin_lock_irqsave(&bus->reg_lock, cookie); - - if (start) - snd_hdac_stream_start(hdac_stream(stream), true); - else - snd_hdac_stream_stop(hdac_stream(stream)); - - if (start) - snd_hdac_stream_timecounter_init(hstr, 0); - - spin_unlock_irqrestore(&bus->reg_lock, cookie); - - return 0; -} static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct hdac_ext_bus *ebus = get_bus_ctx(substream);
- if (ebus->ppcap) - return skl_decoupled_trigger(substream, cmd); - else + if (!ebus->ppcap) return skl_coupled_trigger(substream, cmd); + + return 0; }
/* calculate runtime delay from LPIB */ diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 0c6e7833e652..2f263ddd696d 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -433,7 +433,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
/* Start sinks pipe first */ if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { - ret = skl_run_pipe(ctx, sink_mconfig->pipe); + if (sink_mconfig->pipe->conn_type != + SKL_PIPE_CONN_TYPE_FE) + ret = skl_run_pipe(ctx, + sink_mconfig->pipe); if (ret) return ret; } @@ -475,9 +478,8 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return ret;
/* Start source pipe last after starting all sinks */ - ret = skl_run_pipe(ctx, src_mconfig->pipe); - if (ret) - return ret; + if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) + return skl_run_pipe(ctx, src_mconfig->pipe);
return 0; } @@ -559,7 +561,8 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret;
- ret = skl_run_pipe(ctx, sink_mconfig->pipe); + if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) + ret = skl_run_pipe(ctx, sink_mconfig->pipe); }
return ret;
The patch
ASoC: Intel: Skylake: Fix DSP pipe underrun/overrun issue
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 224829484534062dedd4218f45631a198c4bd55e Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:53 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix DSP pipe underrun/overrun issue
While rigourous testing of SKL drivers, we noticed underuns and overuns and on debug realized that we need to change driver handling of FE pipe startup and shutdown
We need to start DMA and then run pipe together and not split these up. Similarly while stopping we should stop pipe and then DMA in a sequence.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-pcm.c | 133 +++++++++++++++++++-------------- sound/soc/intel/skylake/skl-topology.c | 13 ++-- 2 files changed, 85 insertions(+), 61 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1a9cd00..2517ec5 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -295,29 +295,101 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream, return skl_tplg_be_update_params(dai, &p_params); }
+static int skl_decoupled_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct hdac_ext_bus *ebus = get_bus_ctx(substream); + struct hdac_bus *bus = ebus_to_hbus(ebus); + struct hdac_ext_stream *stream; + int start; + unsigned long cookie; + struct hdac_stream *hstr; + + stream = get_hdac_ext_stream(substream); + hstr = hdac_stream(stream); + + if (!hstr->prepared) + return -EPIPE; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + start = 1; + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + start = 0; + break; + + default: + return -EINVAL; + } + + spin_lock_irqsave(&bus->reg_lock, cookie); + + if (start) { + snd_hdac_stream_start(hdac_stream(stream), true); + snd_hdac_stream_timecounter_init(hstr, 0); + } else { + snd_hdac_stream_stop(hdac_stream(stream)); + } + + spin_unlock_irqrestore(&bus->reg_lock, cookie); + + return 0; +} + static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct skl *skl = get_skl_ctx(dai->dev); struct skl_sst *ctx = skl->skl_sst; struct skl_module_cfg *mconfig; + int ret;
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); if (!mconfig) return -EIO;
switch (cmd) { + case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: + /* + * Start HOST DMA and Start FE Pipe.This is to make sure that + * there are no underrun/overrun in the case when the FE + * pipeline is started but there is a delay in starting the + * DMA channel on the host. + */ + ret = skl_decoupled_trigger(substream, cmd); + if (ret < 0) + return ret; return skl_run_pipe(ctx, mconfig->pipe); + break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - return skl_stop_pipe(ctx, mconfig->pipe); + case SNDRV_PCM_TRIGGER_STOP: + /* + * Stop FE Pipe first and stop DMA. This is to make sure that + * there are no underrun/overrun in the case if there is a delay + * between the two operations. + */ + ret = skl_stop_pipe(ctx, mconfig->pipe); + if (ret < 0) + return ret; + + ret = skl_decoupled_trigger(substream, cmd); + break;
default: - return 0; + return -EINVAL; } + + return 0; }
static int skl_link_hw_params(struct snd_pcm_substream *substream, @@ -685,66 +757,15 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream, return 0; }
-static int skl_decoupled_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct hdac_ext_bus *ebus = get_bus_ctx(substream); - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct hdac_ext_stream *stream; - int start; - unsigned long cookie; - struct hdac_stream *hstr; - - dev_dbg(bus->dev, "In %s cmd=%d streamname=%s\n", __func__, cmd, cpu_dai->name); - - stream = get_hdac_ext_stream(substream); - hstr = hdac_stream(stream); - - if (!hstr->prepared) - return -EPIPE; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - start = 1; - break; - - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - start = 0; - break; - - default: - return -EINVAL; - } - - spin_lock_irqsave(&bus->reg_lock, cookie); - - if (start) - snd_hdac_stream_start(hdac_stream(stream), true); - else - snd_hdac_stream_stop(hdac_stream(stream)); - - if (start) - snd_hdac_stream_timecounter_init(hstr, 0); - - spin_unlock_irqrestore(&bus->reg_lock, cookie); - - return 0; -} static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct hdac_ext_bus *ebus = get_bus_ctx(substream);
- if (ebus->ppcap) - return skl_decoupled_trigger(substream, cmd); - else + if (!ebus->ppcap) return skl_coupled_trigger(substream, cmd); + + return 0; }
/* calculate runtime delay from LPIB */ diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 0c6e783..2f263dd 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -433,7 +433,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
/* Start sinks pipe first */ if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { - ret = skl_run_pipe(ctx, sink_mconfig->pipe); + if (sink_mconfig->pipe->conn_type != + SKL_PIPE_CONN_TYPE_FE) + ret = skl_run_pipe(ctx, + sink_mconfig->pipe); if (ret) return ret; } @@ -475,9 +478,8 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, return ret;
/* Start source pipe last after starting all sinks */ - ret = skl_run_pipe(ctx, src_mconfig->pipe); - if (ret) - return ret; + if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) + return skl_run_pipe(ctx, src_mconfig->pipe);
return 0; } @@ -559,7 +561,8 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, if (ret) return ret;
- ret = skl_run_pipe(ctx, sink_mconfig->pipe); + if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) + ret = skl_run_pipe(ctx, sink_mconfig->pipe); }
return ret;
From: Jeeja KP jeeja.kp@intel.com
ASoC core already checks if BE is active. If BE is active, hw_params callback is ignored. This patch removes the redundant check in driver for copier widget power check in update be hw_params.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 2f263ddd696d..7311cd317d87 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -950,18 +950,13 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai, if (p->connect && is_skl_dsp_widget_type(p->source) && p->source->priv) {
- if (!p->source->power) { - ret = skl_tplg_be_fill_pipe_params( - dai, p->source->priv, - params); - if (ret < 0) - return ret; - } else { - return -EBUSY; - } + ret = skl_tplg_be_fill_pipe_params(dai, + p->source->priv, params); + if (ret < 0) + return ret; } else { - ret = skl_tplg_be_set_src_pipe_params( - dai, p->source, params); + ret = skl_tplg_be_set_src_pipe_params(dai, + p->source, params); if (ret < 0) return ret; } @@ -980,15 +975,10 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai, if (p->connect && is_skl_dsp_widget_type(p->sink) && p->sink->priv) {
- if (!p->sink->power) { - ret = skl_tplg_be_fill_pipe_params( - dai, p->sink->priv, params); - if (ret < 0) - return ret; - } else { - return -EBUSY; - } - + ret = skl_tplg_be_fill_pipe_params(dai, + p->sink->priv, params); + if (ret < 0) + return ret; } else { ret = skl_tplg_be_set_sink_pipe_params( dai, p->sink, params);
The patch
ASoC: Intel: Skylake: Fix to remove be copier widget power check
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 43df6232cab7e110f51aade63b0ed1994c40f4bd Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:54 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to remove be copier widget power check
ASoC core already checks if BE is active. If BE is active, hw_params callback is ignored. This patch removes the redundant check in driver for copier widget power check in update be hw_params.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 2f263dd..7311cd3 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -950,18 +950,13 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai, if (p->connect && is_skl_dsp_widget_type(p->source) && p->source->priv) {
- if (!p->source->power) { - ret = skl_tplg_be_fill_pipe_params( - dai, p->source->priv, - params); - if (ret < 0) - return ret; - } else { - return -EBUSY; - } + ret = skl_tplg_be_fill_pipe_params(dai, + p->source->priv, params); + if (ret < 0) + return ret; } else { - ret = skl_tplg_be_set_src_pipe_params( - dai, p->source, params); + ret = skl_tplg_be_set_src_pipe_params(dai, + p->source, params); if (ret < 0) return ret; } @@ -980,15 +975,10 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai, if (p->connect && is_skl_dsp_widget_type(p->sink) && p->sink->priv) {
- if (!p->sink->power) { - ret = skl_tplg_be_fill_pipe_params( - dai, p->sink->priv, params); - if (ret < 0) - return ret; - } else { - return -EBUSY; - } - + ret = skl_tplg_be_fill_pipe_params(dai, + p->sink->priv, params); + if (ret < 0) + return ret; } else { ret = skl_tplg_be_set_sink_pipe_params( dai, p->sink, params);
From: Hardik T Shah hardik.t.shah@intel.com
The module pin formats are considered homogeneous, but some modules can have different pcm formats on different pins, like reference signal for a module.
This patch add support for configuration of each pin of module and allows us to specify if pins and homogeneous or heterogeneous
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-messages.c | 8 +-- sound/soc/intel/skylake/skl-topology.c | 90 ++++++++++++++++------------ sound/soc/intel/skylake/skl-topology.h | 12 +++- sound/soc/intel/skylake/skl-tplg-interface.h | 18 +++++- 4 files changed, 83 insertions(+), 45 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index ee059589e9f0..07d3bf4a8bdd 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -280,7 +280,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_base_cfg *base_cfg) { - struct skl_module_fmt *format = &mconfig->in_fmt; + struct skl_module_fmt *format = &mconfig->in_fmt[0];
base_cfg->audio_fmt.number_of_channels = (u8)format->channels;
@@ -399,7 +399,7 @@ static void skl_setup_out_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_audio_data_format *out_fmt) { - struct skl_module_fmt *format = &mconfig->out_fmt; + struct skl_module_fmt *format = &mconfig->out_fmt[0];
out_fmt->number_of_channels = (u8)format->channels; out_fmt->s_freq = format->s_freq; @@ -423,7 +423,7 @@ static void skl_set_src_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_src_module_cfg *src_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt; + struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
skl_set_base_module_format(ctx, mconfig, (struct skl_base_cfg *)src_mconfig); @@ -440,7 +440,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_up_down_mixer_cfg *mixer_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt; + struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; int i = 0;
skl_set_base_module_format(ctx, mconfig, diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 7311cd317d87..37e5c4fc0f10 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -129,17 +129,15 @@ static void skl_dump_mconfig(struct skl_sst *ctx, { dev_dbg(ctx->dev, "Dumping config\n"); dev_dbg(ctx->dev, "Input Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg); - dev_dbg(ctx->dev, "valid bit depth = %d\n", - mcfg->in_fmt.valid_bit_depth); + dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels); + dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq); + dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg); + dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth); dev_dbg(ctx->dev, "Output Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq); - dev_dbg(ctx->dev, "valid bit depth = %d\n", - mcfg->out_fmt.valid_bit_depth); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg); + dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels); + dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq); + dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth); + dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); }
static void skl_tplg_update_params(struct skl_module_fmt *fmt, @@ -171,8 +169,9 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, int in_fixup, out_fixup; struct skl_module_fmt *in_fmt, *out_fmt;
- in_fmt = &m_cfg->in_fmt; - out_fmt = &m_cfg->out_fmt; + /* Fixups will be applied to pin 0 only */ + in_fmt = &m_cfg->in_fmt[0]; + out_fmt = &m_cfg->out_fmt[0];
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (is_fe) { @@ -209,18 +208,25 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, struct skl_module_cfg *mcfg) { int multiplier = 1; + struct skl_module_fmt *in_fmt, *out_fmt; + + + /* Since fixups is applied to pin 0 only, ibs, obs needs + * change for pin 0 only + */ + in_fmt = &mcfg->in_fmt[0]; + out_fmt = &mcfg->out_fmt[0];
if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; - - mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) * - (mcfg->in_fmt.channels) * - (mcfg->in_fmt.bit_depth >> 3) * + mcfg->ibs = (in_fmt->s_freq / 1000) * + (mcfg->in_fmt->channels) * + (mcfg->in_fmt->bit_depth >> 3) * multiplier;
- mcfg->obs = (mcfg->out_fmt.s_freq / 1000) * - (mcfg->out_fmt.channels) * - (mcfg->out_fmt.bit_depth >> 3) * + mcfg->obs = (mcfg->out_fmt->s_freq / 1000) * + (mcfg->out_fmt->channels) * + (mcfg->out_fmt->bit_depth >> 3) * multiplier; }
@@ -786,9 +792,9 @@ int skl_tplg_update_pipe_params(struct device *dev, memcpy(pipe->p_params, params, sizeof(*params));
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) - format = &mconfig->in_fmt; + format = &mconfig->in_fmt[0]; else - format = &mconfig->out_fmt; + format = &mconfig->out_fmt[0];
/* set the hw_params */ format->s_freq = params->s_freq; @@ -1083,6 +1089,24 @@ static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, return ppl->pipe; }
+static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, + struct skl_dfw_module_fmt *src_fmt, + int pins) +{ + int i; + + for (i = 0; i < pins; i++) { + dst_fmt[i].channels = src_fmt[i].channels; + dst_fmt[i].s_freq = src_fmt[i].freq; + dst_fmt[i].bit_depth = src_fmt[i].bit_depth; + dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; + dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; + dst_fmt[i].ch_map = src_fmt[i].ch_map; + dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; + dst_fmt[i].sample_type = src_fmt[i].sample_type; + } +} + /* * Topology core widget load callback * @@ -1121,18 +1145,11 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->max_in_queue = dfw_config->max_in_queue; mconfig->max_out_queue = dfw_config->max_out_queue; mconfig->is_loadable = dfw_config->is_loadable; - mconfig->in_fmt.channels = dfw_config->in_fmt.channels; - mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq; - mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth; - mconfig->in_fmt.valid_bit_depth = - dfw_config->in_fmt.valid_bit_depth; - mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg; - mconfig->out_fmt.channels = dfw_config->out_fmt.channels; - mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq; - mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth; - mconfig->out_fmt.valid_bit_depth = - dfw_config->out_fmt.valid_bit_depth; - mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg; + skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt, + MODULE_MAX_IN_PINS); + skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt, + MODULE_MAX_OUT_PINS); + mconfig->params_fixup = dfw_config->params_fixup; mconfig->converter = dfw_config->converter; mconfig->m_type = dfw_config->module_type; @@ -1147,10 +1164,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->time_slot = dfw_config->time_slot; mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
- mconfig->m_in_pin = devm_kzalloc(bus->dev, - (mconfig->max_in_queue) * - sizeof(*mconfig->m_in_pin), - GFP_KERNEL); + mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * + sizeof(*mconfig->m_in_pin), + GFP_KERNEL); if (!mconfig->m_in_pin) return -ENOMEM;
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 1b35cb6c397a..3b63450c6d5e 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -36,6 +36,9 @@ /* Maximum number of coefficients up down mixer module */ #define UP_DOWN_MIXER_MAX_COEFF 6
+#define MODULE_MAX_IN_PINS 8 +#define MODULE_MAX_OUT_PINS 8 + enum skl_channel_index { SKL_CHANNEL_LEFT = 0, SKL_CHANNEL_RIGHT = 1, @@ -178,6 +181,9 @@ struct skl_module_fmt { u32 bit_depth; u32 valid_bit_depth; u32 ch_cfg; + u32 interleaving_style; + u32 sample_type; + u32 ch_map; };
struct skl_module_cfg; @@ -247,8 +253,10 @@ enum skl_module_state {
struct skl_module_cfg { struct skl_module_inst_id id; - struct skl_module_fmt in_fmt; - struct skl_module_fmt out_fmt; + bool homogenous_inputs; + bool homogenous_outputs; + struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS]; + struct skl_module_fmt out_fmt[MODULE_MAX_OUT_PINS]; u8 max_in_queue; u8 max_out_queue; u8 in_queue_mask; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index 2bc396d54cbe..7bd9af7ee15c 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -110,6 +110,17 @@ enum skl_dev_type { SKL_DEVICE_NONE };
+enum module_pin_type { + /* All pins of the module takes same PCM inputs or outputs + * e.g. mixout + */ + SKL_PIN_TYPE_HOMOGENEOUS, + /* All pins of the module takes different PCM inputs or outputs + * e.g mux + */ + SKL_PIN_TYPE_HETEROGENEOUS, +}; + struct skl_dfw_module_pin { u16 module_id; u16 instance_id; @@ -121,6 +132,9 @@ struct skl_dfw_module_fmt { u32 bit_depth; u32 valid_bit_depth; u32 ch_cfg; + u32 interleaving_style; + u32 sample_type; + u32 ch_map; } __packed;
struct skl_dfw_module_caps { @@ -156,8 +170,8 @@ struct skl_dfw_module { u8 is_dynamic_in_pin; u8 is_dynamic_out_pin; struct skl_dfw_pipe pipe; - struct skl_dfw_module_fmt in_fmt; - struct skl_dfw_module_fmt out_fmt; + struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; + struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; struct skl_dfw_module_caps caps;
The patch
ASoC: Intel: Skylake: Add multiple pin formats
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 40766afbe721515846e74cd5f0273c7e515f2c9c Mon Sep 17 00:00:00 2001
From: Hardik T Shah hardik.t.shah@intel.com Date: Tue, 27 Oct 2015 09:22:55 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Add multiple pin formats
The module pin formats are considered homogeneous, but some modules can have different pcm formats on different pins, like reference signal for a module.
This patch add support for configuration of each pin of module and allows us to specify if pins and homogeneous or heterogeneous
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-messages.c | 8 +-- sound/soc/intel/skylake/skl-topology.c | 90 ++++++++++++++++------------ sound/soc/intel/skylake/skl-topology.h | 12 +++- sound/soc/intel/skylake/skl-tplg-interface.h | 18 +++++- 4 files changed, 83 insertions(+), 45 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index ee05958..07d3bf4 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -280,7 +280,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_base_cfg *base_cfg) { - struct skl_module_fmt *format = &mconfig->in_fmt; + struct skl_module_fmt *format = &mconfig->in_fmt[0];
base_cfg->audio_fmt.number_of_channels = (u8)format->channels;
@@ -399,7 +399,7 @@ static void skl_setup_out_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_audio_data_format *out_fmt) { - struct skl_module_fmt *format = &mconfig->out_fmt; + struct skl_module_fmt *format = &mconfig->out_fmt[0];
out_fmt->number_of_channels = (u8)format->channels; out_fmt->s_freq = format->s_freq; @@ -423,7 +423,7 @@ static void skl_set_src_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_src_module_cfg *src_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt; + struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
skl_set_base_module_format(ctx, mconfig, (struct skl_base_cfg *)src_mconfig); @@ -440,7 +440,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_up_down_mixer_cfg *mixer_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt; + struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; int i = 0;
skl_set_base_module_format(ctx, mconfig, diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 7311cd3..37e5c4f 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -129,17 +129,15 @@ static void skl_dump_mconfig(struct skl_sst *ctx, { dev_dbg(ctx->dev, "Dumping config\n"); dev_dbg(ctx->dev, "Input Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg); - dev_dbg(ctx->dev, "valid bit depth = %d\n", - mcfg->in_fmt.valid_bit_depth); + dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels); + dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq); + dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg); + dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth); dev_dbg(ctx->dev, "Output Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq); - dev_dbg(ctx->dev, "valid bit depth = %d\n", - mcfg->out_fmt.valid_bit_depth); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg); + dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels); + dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq); + dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth); + dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); }
static void skl_tplg_update_params(struct skl_module_fmt *fmt, @@ -171,8 +169,9 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, int in_fixup, out_fixup; struct skl_module_fmt *in_fmt, *out_fmt;
- in_fmt = &m_cfg->in_fmt; - out_fmt = &m_cfg->out_fmt; + /* Fixups will be applied to pin 0 only */ + in_fmt = &m_cfg->in_fmt[0]; + out_fmt = &m_cfg->out_fmt[0];
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (is_fe) { @@ -209,18 +208,25 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, struct skl_module_cfg *mcfg) { int multiplier = 1; + struct skl_module_fmt *in_fmt, *out_fmt; + + + /* Since fixups is applied to pin 0 only, ibs, obs needs + * change for pin 0 only + */ + in_fmt = &mcfg->in_fmt[0]; + out_fmt = &mcfg->out_fmt[0];
if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; - - mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) * - (mcfg->in_fmt.channels) * - (mcfg->in_fmt.bit_depth >> 3) * + mcfg->ibs = (in_fmt->s_freq / 1000) * + (mcfg->in_fmt->channels) * + (mcfg->in_fmt->bit_depth >> 3) * multiplier;
- mcfg->obs = (mcfg->out_fmt.s_freq / 1000) * - (mcfg->out_fmt.channels) * - (mcfg->out_fmt.bit_depth >> 3) * + mcfg->obs = (mcfg->out_fmt->s_freq / 1000) * + (mcfg->out_fmt->channels) * + (mcfg->out_fmt->bit_depth >> 3) * multiplier; }
@@ -786,9 +792,9 @@ int skl_tplg_update_pipe_params(struct device *dev, memcpy(pipe->p_params, params, sizeof(*params));
if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) - format = &mconfig->in_fmt; + format = &mconfig->in_fmt[0]; else - format = &mconfig->out_fmt; + format = &mconfig->out_fmt[0];
/* set the hw_params */ format->s_freq = params->s_freq; @@ -1083,6 +1089,24 @@ static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, return ppl->pipe; }
+static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, + struct skl_dfw_module_fmt *src_fmt, + int pins) +{ + int i; + + for (i = 0; i < pins; i++) { + dst_fmt[i].channels = src_fmt[i].channels; + dst_fmt[i].s_freq = src_fmt[i].freq; + dst_fmt[i].bit_depth = src_fmt[i].bit_depth; + dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; + dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; + dst_fmt[i].ch_map = src_fmt[i].ch_map; + dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; + dst_fmt[i].sample_type = src_fmt[i].sample_type; + } +} + /* * Topology core widget load callback * @@ -1121,18 +1145,11 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->max_in_queue = dfw_config->max_in_queue; mconfig->max_out_queue = dfw_config->max_out_queue; mconfig->is_loadable = dfw_config->is_loadable; - mconfig->in_fmt.channels = dfw_config->in_fmt.channels; - mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq; - mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth; - mconfig->in_fmt.valid_bit_depth = - dfw_config->in_fmt.valid_bit_depth; - mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg; - mconfig->out_fmt.channels = dfw_config->out_fmt.channels; - mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq; - mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth; - mconfig->out_fmt.valid_bit_depth = - dfw_config->out_fmt.valid_bit_depth; - mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg; + skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt, + MODULE_MAX_IN_PINS); + skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt, + MODULE_MAX_OUT_PINS); + mconfig->params_fixup = dfw_config->params_fixup; mconfig->converter = dfw_config->converter; mconfig->m_type = dfw_config->module_type; @@ -1147,10 +1164,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->time_slot = dfw_config->time_slot; mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
- mconfig->m_in_pin = devm_kzalloc(bus->dev, - (mconfig->max_in_queue) * - sizeof(*mconfig->m_in_pin), - GFP_KERNEL); + mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * + sizeof(*mconfig->m_in_pin), + GFP_KERNEL); if (!mconfig->m_in_pin) return -ENOMEM;
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 1b35cb6..3b63450 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -36,6 +36,9 @@ /* Maximum number of coefficients up down mixer module */ #define UP_DOWN_MIXER_MAX_COEFF 6
+#define MODULE_MAX_IN_PINS 8 +#define MODULE_MAX_OUT_PINS 8 + enum skl_channel_index { SKL_CHANNEL_LEFT = 0, SKL_CHANNEL_RIGHT = 1, @@ -178,6 +181,9 @@ struct skl_module_fmt { u32 bit_depth; u32 valid_bit_depth; u32 ch_cfg; + u32 interleaving_style; + u32 sample_type; + u32 ch_map; };
struct skl_module_cfg; @@ -247,8 +253,10 @@ enum skl_module_state {
struct skl_module_cfg { struct skl_module_inst_id id; - struct skl_module_fmt in_fmt; - struct skl_module_fmt out_fmt; + bool homogenous_inputs; + bool homogenous_outputs; + struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS]; + struct skl_module_fmt out_fmt[MODULE_MAX_OUT_PINS]; u8 max_in_queue; u8 max_out_queue; u8 in_queue_mask; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index 2bc396d..7bd9af7 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -110,6 +110,17 @@ enum skl_dev_type { SKL_DEVICE_NONE };
+enum module_pin_type { + /* All pins of the module takes same PCM inputs or outputs + * e.g. mixout + */ + SKL_PIN_TYPE_HOMOGENEOUS, + /* All pins of the module takes different PCM inputs or outputs + * e.g mux + */ + SKL_PIN_TYPE_HETEROGENEOUS, +}; + struct skl_dfw_module_pin { u16 module_id; u16 instance_id; @@ -121,6 +132,9 @@ struct skl_dfw_module_fmt { u32 bit_depth; u32 valid_bit_depth; u32 ch_cfg; + u32 interleaving_style; + u32 sample_type; + u32 ch_map; } __packed;
struct skl_dfw_module_caps { @@ -156,8 +170,8 @@ struct skl_dfw_module { u8 is_dynamic_in_pin; u8 is_dynamic_out_pin; struct skl_dfw_pipe pipe; - struct skl_dfw_module_fmt in_fmt; - struct skl_dfw_module_fmt out_fmt; + struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; + struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; struct skl_dfw_module_caps caps;
From: Hardik T Shah hardik.t.shah@intel.com
This patch updates the topology interface structure alignment and also updates the Sample interleaving defines
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.h | 7 +-- sound/soc/intel/skylake/skl-tplg-interface.h | 69 +++++++++++++++++++++------- 2 files changed, 54 insertions(+), 22 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 3b63450c6d5e..4b0a59898676 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -58,12 +58,6 @@ enum skl_bitdepth { SKL_DEPTH_INVALID };
-enum skl_interleaving { - /* [s1_ch1...s1_chN,...,sM_ch1...sM_chN] */ - SKL_INTERLEAVING_PER_CHANNEL = 0, - /* [s1_ch1...sM_ch1,...,s1_chN...sM_chN] */ - SKL_INTERLEAVING_PER_SAMPLE = 1, -};
enum skl_s_freq { SKL_FS_8000 = 8000, @@ -253,6 +247,7 @@ enum skl_module_state {
struct skl_module_cfg { struct skl_module_inst_id id; + u8 domain; bool homogenous_inputs; bool homogenous_outputs; struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS]; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index 7bd9af7ee15c..aeb8f251675a 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -72,6 +72,7 @@ enum skl_ch_cfg { SKL_CH_CFG_DUAL_MONO = 9, SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10, SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11, + SKL_CH_CFG_4_CHANNEL = 12, SKL_CH_CFG_INVALID };
@@ -110,6 +111,25 @@ enum skl_dev_type { SKL_DEVICE_NONE };
+/** + * enum skl_interleaving - interleaving style + * + * @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN] + * @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN] + */ +enum skl_interleaving { + SKL_INTERLEAVING_PER_CHANNEL = 0, + SKL_INTERLEAVING_PER_SAMPLE = 1, +}; + +enum skl_sample_type { + SKL_SAMPLE_TYPE_INT_MSB = 0, + SKL_SAMPLE_TYPE_INT_LSB = 1, + SKL_SAMPLE_TYPE_INT_SIGNED = 2, + SKL_SAMPLE_TYPE_INT_UNSIGNED = 3, + SKL_SAMPLE_TYPE_FLOAT = 4 +}; + enum module_pin_type { /* All pins of the module takes same PCM inputs or outputs * e.g. mixout @@ -138,6 +158,9 @@ struct skl_dfw_module_fmt { } __packed;
struct skl_dfw_module_caps { + u32 set_params:1; + u32 rsvd:31; + u32 param_id; u32 caps_size; u32 caps[HDA_SST_CFG_MAX]; }; @@ -145,30 +168,41 @@ struct skl_dfw_module_caps { struct skl_dfw_pipe { u8 pipe_id; u8 pipe_priority; - u16 conn_type; - u32 memory_pages; + u16 conn_type:4; + u16 rsvd:4; + u16 memory_pages:8; } __packed;
struct skl_dfw_module { u16 module_id; u16 instance_id; u32 max_mcps; - u8 core_id; - u8 max_in_queue; - u8 max_out_queue; - u8 is_loadable; - u8 conn_type; - u8 dev_type; - u8 hw_conn_type; - u8 time_slot; + u32 mem_pages; u32 obs; u32 ibs; - u32 params_fixup; - u32 converter; - u32 module_type; u32 vbus_id; - u8 is_dynamic_in_pin; - u8 is_dynamic_out_pin; + + u32 max_in_queue:8; + u32 max_out_queue:8; + u32 time_slot:8; + u32 core_id:4; + u32 rsvd1:4; + + u32 module_type:8; + u32 conn_type:4; + u32 dev_type:4; + u32 hw_conn_type:4; + u32 rsvd2:12; + + u32 params_fixup:8; + u32 converter:8; + u32 input_pin_type:1; + u32 output_pin_type:1; + u32 is_dynamic_in_pin:1; + u32 is_dynamic_out_pin:1; + u32 is_loadable:1; + u32 rsvd3:11; + struct skl_dfw_pipe pipe; struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; @@ -178,8 +212,11 @@ struct skl_dfw_module { } __packed;
struct skl_dfw_algo_data { + u32 set_params:1; + u32 rsvd:31; + u32 param_id; u32 max; - char *params; + char params[0]; } __packed;
#endif
The patch
ASoC: Intel: Skylake: Update the topology interface structure
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From be3ba434fc8f133c0fc406c2b51c9b5279ff9f0e Mon Sep 17 00:00:00 2001
From: Hardik T Shah hardik.t.shah@intel.com Date: Tue, 27 Oct 2015 09:22:56 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Update the topology interface structure
This patch updates the topology interface structure alignment and also updates the Sample interleaving defines
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.h | 7 +-- sound/soc/intel/skylake/skl-tplg-interface.h | 69 +++++++++++++++++++++------- 2 files changed, 54 insertions(+), 22 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 3b63450..4b0a59898 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -58,12 +58,6 @@ enum skl_bitdepth { SKL_DEPTH_INVALID };
-enum skl_interleaving { - /* [s1_ch1...s1_chN,...,sM_ch1...sM_chN] */ - SKL_INTERLEAVING_PER_CHANNEL = 0, - /* [s1_ch1...sM_ch1,...,s1_chN...sM_chN] */ - SKL_INTERLEAVING_PER_SAMPLE = 1, -};
enum skl_s_freq { SKL_FS_8000 = 8000, @@ -253,6 +247,7 @@ enum skl_module_state {
struct skl_module_cfg { struct skl_module_inst_id id; + u8 domain; bool homogenous_inputs; bool homogenous_outputs; struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS]; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index 7bd9af7..aeb8f25 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -72,6 +72,7 @@ enum skl_ch_cfg { SKL_CH_CFG_DUAL_MONO = 9, SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10, SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11, + SKL_CH_CFG_4_CHANNEL = 12, SKL_CH_CFG_INVALID };
@@ -110,6 +111,25 @@ enum skl_dev_type { SKL_DEVICE_NONE };
+/** + * enum skl_interleaving - interleaving style + * + * @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN] + * @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN] + */ +enum skl_interleaving { + SKL_INTERLEAVING_PER_CHANNEL = 0, + SKL_INTERLEAVING_PER_SAMPLE = 1, +}; + +enum skl_sample_type { + SKL_SAMPLE_TYPE_INT_MSB = 0, + SKL_SAMPLE_TYPE_INT_LSB = 1, + SKL_SAMPLE_TYPE_INT_SIGNED = 2, + SKL_SAMPLE_TYPE_INT_UNSIGNED = 3, + SKL_SAMPLE_TYPE_FLOAT = 4 +}; + enum module_pin_type { /* All pins of the module takes same PCM inputs or outputs * e.g. mixout @@ -138,6 +158,9 @@ struct skl_dfw_module_fmt { } __packed;
struct skl_dfw_module_caps { + u32 set_params:1; + u32 rsvd:31; + u32 param_id; u32 caps_size; u32 caps[HDA_SST_CFG_MAX]; }; @@ -145,30 +168,41 @@ struct skl_dfw_module_caps { struct skl_dfw_pipe { u8 pipe_id; u8 pipe_priority; - u16 conn_type; - u32 memory_pages; + u16 conn_type:4; + u16 rsvd:4; + u16 memory_pages:8; } __packed;
struct skl_dfw_module { u16 module_id; u16 instance_id; u32 max_mcps; - u8 core_id; - u8 max_in_queue; - u8 max_out_queue; - u8 is_loadable; - u8 conn_type; - u8 dev_type; - u8 hw_conn_type; - u8 time_slot; + u32 mem_pages; u32 obs; u32 ibs; - u32 params_fixup; - u32 converter; - u32 module_type; u32 vbus_id; - u8 is_dynamic_in_pin; - u8 is_dynamic_out_pin; + + u32 max_in_queue:8; + u32 max_out_queue:8; + u32 time_slot:8; + u32 core_id:4; + u32 rsvd1:4; + + u32 module_type:8; + u32 conn_type:4; + u32 dev_type:4; + u32 hw_conn_type:4; + u32 rsvd2:12; + + u32 params_fixup:8; + u32 converter:8; + u32 input_pin_type:1; + u32 output_pin_type:1; + u32 is_dynamic_in_pin:1; + u32 is_dynamic_out_pin:1; + u32 is_loadable:1; + u32 rsvd3:11; + struct skl_dfw_pipe pipe; struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; @@ -178,8 +212,11 @@ struct skl_dfw_module { } __packed;
struct skl_dfw_algo_data { + u32 set_params:1; + u32 rsvd:31; + u32 param_id; u32 max; - char *params; + char params[0]; } __packed;
#endif
From: Hardik T Shah hardik.t.shah@intel.com
The DSP FW specifies loadable modules using GUIDs so add support to specify the GUIDs from topology
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-topology.c | 4 ++++ sound/soc/intel/skylake/skl-topology.h | 1 + sound/soc/intel/skylake/skl-tplg-interface.h | 3 +++ 3 files changed, 8 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 37e5c4fc0f10..3c5f06235889 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1164,6 +1164,10 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->time_slot = dfw_config->time_slot; mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
+ if (dfw_config->is_loadable) + memcpy(mconfig->guid, dfw_config->uuid, + ARRAY_SIZE(dfw_config->uuid)); + mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * sizeof(*mconfig->m_in_pin), GFP_KERNEL); diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 4b0a59898676..57cb7b8dd269 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -246,6 +246,7 @@ enum skl_module_state { };
struct skl_module_cfg { + char guid[SKL_UUID_STR_SZ]; struct skl_module_inst_id id; u8 domain; bool homogenous_inputs; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index aeb8f251675a..20c068754d08 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -32,6 +32,7 @@ #define MAX_IN_QUEUE 8 #define MAX_OUT_QUEUE 8
+#define SKL_UUID_STR_SZ 40 /* Event types goes here */ /* Reserve event type 0 for no event handlers */ enum skl_event_types { @@ -174,6 +175,8 @@ struct skl_dfw_pipe { } __packed;
struct skl_dfw_module { + char uuid[SKL_UUID_STR_SZ]; + u16 module_id; u16 instance_id; u32 max_mcps;
The patch
ASoC: Intel: Skylake: Add support for module GUIDs
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 16b52e8a4f208a613a347fba8bc45bfd50f7e922 Mon Sep 17 00:00:00 2001
From: Hardik T Shah hardik.t.shah@intel.com Date: Tue, 27 Oct 2015 09:22:57 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Add support for module GUIDs
The DSP FW specifies loadable modules using GUIDs so add support to specify the GUIDs from topology
Signed-off-by: Hardik T Shah hardik.t.shah@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-topology.c | 4 ++++ sound/soc/intel/skylake/skl-topology.h | 1 + sound/soc/intel/skylake/skl-tplg-interface.h | 3 +++ 3 files changed, 8 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 37e5c4f..3c5f062 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1164,6 +1164,10 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, mconfig->time_slot = dfw_config->time_slot; mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
+ if (dfw_config->is_loadable) + memcpy(mconfig->guid, dfw_config->uuid, + ARRAY_SIZE(dfw_config->uuid)); + mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * sizeof(*mconfig->m_in_pin), GFP_KERNEL); diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 4b0a59898..57cb7b8 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -246,6 +246,7 @@ enum skl_module_state { };
struct skl_module_cfg { + char guid[SKL_UUID_STR_SZ]; struct skl_module_inst_id id; u8 domain; bool homogenous_inputs; diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index aeb8f25..20c0687 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h @@ -32,6 +32,7 @@ #define MAX_IN_QUEUE 8 #define MAX_OUT_QUEUE 8
+#define SKL_UUID_STR_SZ 40 /* Event types goes here */ /* Reserve event type 0 for no event handlers */ enum skl_event_types { @@ -174,6 +175,8 @@ struct skl_dfw_pipe { } __packed;
struct skl_dfw_module { + char uuid[SKL_UUID_STR_SZ]; + u16 module_id; u16 instance_id; u32 max_mcps;
From: Jeeja KP jeeja.kp@intel.com
DMIC NHLT entry is sample rate agnostic, so ignore the rate checks for DMIC type
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-nhlt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index 3ff22eba5875..6e4b21cdb1bd 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c @@ -55,7 +55,7 @@ void skl_nhlt_free(void *addr)
static struct nhlt_specific_cfg *skl_get_specific_cfg( struct device *dev, struct nhlt_fmt *fmt, - u8 no_ch, u32 rate, u16 bps) + u8 no_ch, u32 rate, u16 bps, u8 linktype) { struct nhlt_specific_cfg *sp_config; struct wav_fmt *wfmt; @@ -68,11 +68,17 @@ static struct nhlt_specific_cfg *skl_get_specific_cfg( wfmt = &fmt_config->fmt_ext.fmt; dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels, wfmt->bits_per_sample, wfmt->samples_per_sec); - if (wfmt->channels == no_ch && wfmt->samples_per_sec == rate && - wfmt->bits_per_sample == bps) { + if (wfmt->channels == no_ch && wfmt->bits_per_sample == bps) { + /* + * if link type is dmic ignore rate check as the blob is + * generic for all rates + */ sp_config = &fmt_config->config; + if (linktype == NHLT_LINK_DMIC) + return sp_config;
- return sp_config; + if (wfmt->samples_per_sec == rate) + return sp_config; }
fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps + @@ -128,7 +134,8 @@ struct nhlt_specific_cfg if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) { fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); - sp_config = skl_get_specific_cfg(dev, fmt, num_ch, s_rate, bps); + sp_config = skl_get_specific_cfg(dev, fmt, num_ch, + s_rate, bps, link_type); if (sp_config) return sp_config; }
The patch
ASoC: Intel: Skylake: Ignore rate check for DMIC link
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From d7a8b1e660fe9703b61129bcb736ea2eb9a15cdc Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:58 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Ignore rate check for DMIC link
DMIC NHLT entry is sample rate agnostic, so ignore the rate checks for DMIC type
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-nhlt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index 3ff22eb..6e4b21c 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c @@ -55,7 +55,7 @@ void skl_nhlt_free(void *addr)
static struct nhlt_specific_cfg *skl_get_specific_cfg( struct device *dev, struct nhlt_fmt *fmt, - u8 no_ch, u32 rate, u16 bps) + u8 no_ch, u32 rate, u16 bps, u8 linktype) { struct nhlt_specific_cfg *sp_config; struct wav_fmt *wfmt; @@ -68,11 +68,17 @@ static struct nhlt_specific_cfg *skl_get_specific_cfg( wfmt = &fmt_config->fmt_ext.fmt; dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels, wfmt->bits_per_sample, wfmt->samples_per_sec); - if (wfmt->channels == no_ch && wfmt->samples_per_sec == rate && - wfmt->bits_per_sample == bps) { + if (wfmt->channels == no_ch && wfmt->bits_per_sample == bps) { + /* + * if link type is dmic ignore rate check as the blob is + * generic for all rates + */ sp_config = &fmt_config->config; + if (linktype == NHLT_LINK_DMIC) + return sp_config;
- return sp_config; + if (wfmt->samples_per_sec == rate) + return sp_config; }
fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps + @@ -128,7 +134,8 @@ struct nhlt_specific_cfg if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) { fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); - sp_config = skl_get_specific_cfg(dev, fmt, num_ch, s_rate, bps); + sp_config = skl_get_specific_cfg(dev, fmt, num_ch, + s_rate, bps, link_type); if (sp_config) return sp_config; }
From: Jeeja KP jeeja.kp@intel.com
Widget FW topology private data already has the information on the channel map, ch_cfg and interleaving. This patch removes the calculation of channel_map in driver and reads the value directly from widget private data.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl-messages.c | 98 ++-------------------------------- 1 file changed, 5 insertions(+), 93 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 07d3bf4a8bdd..bfde60bb8119 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -182,94 +182,6 @@ enum skl_bitdepth skl_get_bit_depth(int params) } }
-static u32 skl_create_channel_map(enum skl_ch_cfg ch_cfg) -{ - u32 config; - - switch (ch_cfg) { - case SKL_CH_CFG_MONO: - config = (0xFFFFFFF0 | SKL_CHANNEL_LEFT); - break; - - case SKL_CH_CFG_STEREO: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4)); - break; - - case SKL_CH_CFG_2_1: - config = (0xFFFFF000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4) - | (SKL_CHANNEL_LFE << 8)); - break; - - case SKL_CH_CFG_3_0: - config = (0xFFFFF000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8)); - break; - - case SKL_CH_CFG_3_1: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LFE << 12)); - break; - - case SKL_CH_CFG_QUATRO: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4) - | (SKL_CHANNEL_LEFT_SURROUND << 8) - | (SKL_CHANNEL_RIGHT_SURROUND << 12)); - break; - - case SKL_CH_CFG_4_0: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_CENTER_SURROUND << 12)); - break; - - case SKL_CH_CFG_5_0: - config = (0xFFF00000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LEFT_SURROUND << 12) - | (SKL_CHANNEL_RIGHT_SURROUND << 16)); - break; - - case SKL_CH_CFG_5_1: - config = (0xFF000000 | SKL_CHANNEL_CENTER - | (SKL_CHANNEL_LEFT << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LEFT_SURROUND << 12) - | (SKL_CHANNEL_RIGHT_SURROUND << 16) - | (SKL_CHANNEL_LFE << 20)); - break; - - case SKL_CH_CFG_DUAL_MONO: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_LEFT << 4)); - break; - - case SKL_CH_CFG_I2S_DUAL_STEREO_0: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4)); - break; - - case SKL_CH_CFG_I2S_DUAL_STEREO_1: - config = (0xFFFF00FF | (SKL_CHANNEL_LEFT << 8) - | (SKL_CHANNEL_RIGHT << 12)); - break; - - default: - config = 0xFFFFFFFF; - break; - - } - - return config; -} - /* * Each module in DSP expects a base module configuration, which consists of * PCM format information, which we calculate in driver and resource values @@ -293,10 +205,9 @@ static void skl_set_base_module_format(struct skl_sst *ctx, format->bit_depth, format->valid_bit_depth, format->ch_cfg);
- base_cfg->audio_fmt.channel_map = skl_create_channel_map( - base_cfg->audio_fmt.ch_cfg); + base_cfg->audio_fmt.channel_map = format->ch_map;
- base_cfg->audio_fmt.interleaving = SKL_INTERLEAVING_PER_CHANNEL; + base_cfg->audio_fmt.interleaving = format->interleaving_style;
base_cfg->cps = mconfig->mcps; base_cfg->ibs = mconfig->ibs; @@ -407,8 +318,9 @@ static void skl_setup_out_format(struct skl_sst *ctx, out_fmt->valid_bit_depth = format->valid_bit_depth; out_fmt->ch_cfg = format->ch_cfg;
- out_fmt->channel_map = skl_create_channel_map(out_fmt->ch_cfg); - out_fmt->interleaving = SKL_INTERLEAVING_PER_CHANNEL; + out_fmt->channel_map = format->ch_map; + out_fmt->interleaving = format->interleaving_style; + out_fmt->sample_type = format->sample_type;
dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", out_fmt->number_of_channels, format->s_freq, format->bit_depth);
The patch
ASoC: Intel: Skylake: Fix to remove channel_map calculation
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 05c68bc3d7a15ee06694ee2b53d08e0551296a51 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:22:59 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix to remove channel_map calculation
Widget FW topology private data already has the information on the channel map, ch_cfg and interleaving. This patch removes the calculation of channel_map in driver and reads the value directly from widget private data.
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-messages.c | 98 ++-------------------------------- 1 file changed, 5 insertions(+), 93 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 07d3bf4..bfde60b 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -182,94 +182,6 @@ enum skl_bitdepth skl_get_bit_depth(int params) } }
-static u32 skl_create_channel_map(enum skl_ch_cfg ch_cfg) -{ - u32 config; - - switch (ch_cfg) { - case SKL_CH_CFG_MONO: - config = (0xFFFFFFF0 | SKL_CHANNEL_LEFT); - break; - - case SKL_CH_CFG_STEREO: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4)); - break; - - case SKL_CH_CFG_2_1: - config = (0xFFFFF000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4) - | (SKL_CHANNEL_LFE << 8)); - break; - - case SKL_CH_CFG_3_0: - config = (0xFFFFF000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8)); - break; - - case SKL_CH_CFG_3_1: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LFE << 12)); - break; - - case SKL_CH_CFG_QUATRO: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4) - | (SKL_CHANNEL_LEFT_SURROUND << 8) - | (SKL_CHANNEL_RIGHT_SURROUND << 12)); - break; - - case SKL_CH_CFG_4_0: - config = (0xFFFF0000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_CENTER_SURROUND << 12)); - break; - - case SKL_CH_CFG_5_0: - config = (0xFFF00000 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_CENTER << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LEFT_SURROUND << 12) - | (SKL_CHANNEL_RIGHT_SURROUND << 16)); - break; - - case SKL_CH_CFG_5_1: - config = (0xFF000000 | SKL_CHANNEL_CENTER - | (SKL_CHANNEL_LEFT << 4) - | (SKL_CHANNEL_RIGHT << 8) - | (SKL_CHANNEL_LEFT_SURROUND << 12) - | (SKL_CHANNEL_RIGHT_SURROUND << 16) - | (SKL_CHANNEL_LFE << 20)); - break; - - case SKL_CH_CFG_DUAL_MONO: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_LEFT << 4)); - break; - - case SKL_CH_CFG_I2S_DUAL_STEREO_0: - config = (0xFFFFFF00 | SKL_CHANNEL_LEFT - | (SKL_CHANNEL_RIGHT << 4)); - break; - - case SKL_CH_CFG_I2S_DUAL_STEREO_1: - config = (0xFFFF00FF | (SKL_CHANNEL_LEFT << 8) - | (SKL_CHANNEL_RIGHT << 12)); - break; - - default: - config = 0xFFFFFFFF; - break; - - } - - return config; -} - /* * Each module in DSP expects a base module configuration, which consists of * PCM format information, which we calculate in driver and resource values @@ -293,10 +205,9 @@ static void skl_set_base_module_format(struct skl_sst *ctx, format->bit_depth, format->valid_bit_depth, format->ch_cfg);
- base_cfg->audio_fmt.channel_map = skl_create_channel_map( - base_cfg->audio_fmt.ch_cfg); + base_cfg->audio_fmt.channel_map = format->ch_map;
- base_cfg->audio_fmt.interleaving = SKL_INTERLEAVING_PER_CHANNEL; + base_cfg->audio_fmt.interleaving = format->interleaving_style;
base_cfg->cps = mconfig->mcps; base_cfg->ibs = mconfig->ibs; @@ -407,8 +318,9 @@ static void skl_setup_out_format(struct skl_sst *ctx, out_fmt->valid_bit_depth = format->valid_bit_depth; out_fmt->ch_cfg = format->ch_cfg;
- out_fmt->channel_map = skl_create_channel_map(out_fmt->ch_cfg); - out_fmt->interleaving = SKL_INTERLEAVING_PER_CHANNEL; + out_fmt->channel_map = format->ch_map; + out_fmt->interleaving = format->interleaving_style; + out_fmt->sample_type = format->sample_type;
dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", out_fmt->number_of_channels, format->s_freq, format->bit_depth);
From: Jeeja KP jeeja.kp@intel.com
The driver runtime behaviour is fine but in suspend, we missed setting the DSP to suspend and also missed resuming DSP on resume.
Fix this by having common SKL suspend and resume routines which power up/down links, suspend/resume DSP and other common routines, and call these routines from both runtime as well as system PM handlers
Signed-off-by: Jayachandran B jayachandran.b@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl.c | 60 +++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 211ef6e2fa21..9b94a8cdf9bd 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -129,6 +129,37 @@ static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect) return 0; }
+#ifdef CONFIG_PM +static int _skl_suspend(struct hdac_ext_bus *ebus) +{ + struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = ebus_to_hbus(ebus); + int ret; + + snd_hdac_ext_bus_link_power_down_all(ebus); + + ret = skl_suspend_dsp(skl); + if (ret < 0) + return ret; + + snd_hdac_bus_stop_chip(bus); + snd_hdac_bus_enter_link_reset(bus); + + return 0; +} + +static int _skl_resume(struct hdac_ext_bus *ebus) +{ + struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = ebus_to_hbus(ebus); + + skl_init_pci(skl); + snd_hdac_bus_init_chip(bus, true); + + return skl_resume_dsp(skl); +} +#endif + #ifdef CONFIG_PM_SLEEP /* * power management @@ -137,26 +168,16 @@ static int skl_suspend(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); - - snd_hdac_bus_stop_chip(bus); - snd_hdac_bus_enter_link_reset(bus);
- return 0; + return _skl_suspend(ebus); }
static int skl_resume(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *hda = ebus_to_skl(ebus); - - skl_init_pci(hda);
- snd_hdac_bus_init_chip(bus, 1); - - return 0; + return _skl_resume(ebus); } #endif /* CONFIG_PM_SLEEP */
@@ -166,24 +187,13 @@ static int skl_runtime_suspend(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *skl = ebus_to_skl(ebus); - int ret;
dev_dbg(bus->dev, "in %s\n", __func__);
/* enable controller wake up event */ snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
- snd_hdac_ext_bus_link_power_down_all(ebus); - - ret = skl_suspend_dsp(skl); - if (ret < 0) - return ret; - - snd_hdac_bus_stop_chip(bus); - snd_hdac_bus_enter_link_reset(bus); - - return 0; + return _skl_suspend(ebus); }
static int skl_runtime_resume(struct device *dev) @@ -204,7 +214,7 @@ static int skl_runtime_resume(struct device *dev) /* disable controller Wake Up event */ snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
- return skl_resume_dsp(skl); + return _skl_resume(ebus); } #endif /* CONFIG_PM */
From: Jeeja KP jeeja.kp@intel.com
SSP0 FMT uses 24 bits so fix to the value to 24 bits
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/boards/skl_rt286.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index a73a431bd8b7..e6af48491229 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -112,12 +112,15 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The output is 48KHz, stereo, 16bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+ /* set SSP0 to 24 bit */ + snd_mask_none(fmt); + snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); return 0; }
From: Jeeja KP jeeja.kp@intel.com
The UEFI BIOS does not create a machine entry for Linux devices so add a table style machine registration to fix this missing entry
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Omair M Abdullah omair.m.abdullah@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/skylake/skl.c | 79 +++++++++++++++++++++++++++++++++++++++++-- sound/soc/intel/skylake/skl.h | 1 + 2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 9b94a8cdf9bd..e399a6734cf9 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -28,6 +28,11 @@ #include <sound/pcm.h> #include "skl.h"
+struct sst_machines { + char *codec_id; + char *machine; +}; + /* * initialize the PCI registers */ @@ -251,6 +256,64 @@ static int skl_free(struct hdac_ext_bus *ebus) return 0; }
+static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level, + void *context, void **ret) +{ + *(bool *)context = true; + return AE_OK; +} + +static struct sst_machines *sst_acpi_find_machine( + struct sst_machines *machines) +{ + struct sst_machines *mach; + bool found = false; + + for (mach = machines; mach->codec_id; mach++) + if (ACPI_SUCCESS(acpi_get_devices(mach->codec_id, + sst_acpi_mach_match, + &found, NULL)) && found) + return mach; + + return NULL; +} + +static int skl_machine_device_register(struct skl *skl, void *driver_data) +{ + struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); + struct platform_device *pdev; + struct sst_machines *mach = driver_data; + int ret; + + mach = sst_acpi_find_machine(mach); + if (mach == NULL) { + dev_err(bus->dev, "No matching machine driver found\n"); + return -ENODEV; + } + + pdev = platform_device_alloc(mach->machine, -1); + if (pdev == NULL) { + dev_err(bus->dev, "platform device alloc failed\n"); + return -EIO; + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(bus->dev, "failed to add machine device\n"); + platform_device_put(pdev); + return -EIO; + } + skl->i2s_dev = pdev; + + return 0; +} + +static void skl_machine_device_unregister(struct skl *skl) +{ + if (skl->i2s_dev) + platform_device_unregister(skl->i2s_dev); +} + static int skl_dmic_device_register(struct skl *skl) { struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); @@ -484,6 +547,10 @@ static int skl_probe(struct pci_dev *pci, dev_dbg(bus->dev, "error failed to register dsp\n"); goto out_free; } + err = skl_machine_device_register(skl, + (void *)pci_id->driver_data); + if (err < 0) + goto out_dsp_free; } if (ebus->mlcap) snd_hdac_ext_bus_get_ml_capabilities(ebus); @@ -491,7 +558,7 @@ static int skl_probe(struct pci_dev *pci, /* create device for soc dmic */ err = skl_dmic_device_register(skl); if (err < 0) - goto out_dsp_free; + goto out_mach_free;
/* register platform dai and controls */ err = skl_platform_register(bus->dev); @@ -515,6 +582,8 @@ out_unregister: skl_platform_unregister(bus->dev); out_dmic_free: skl_dmic_device_unregister(skl); +out_mach_free: + skl_machine_device_unregister(skl); out_dsp_free: skl_free_dsp(skl); out_free: @@ -534,15 +603,21 @@ static void skl_remove(struct pci_dev *pci) pci_dev_put(pci); skl_platform_unregister(&pci->dev); skl_free_dsp(skl); + skl_machine_device_unregister(skl); skl_dmic_device_unregister(skl); skl_free(ebus); dev_set_drvdata(&pci->dev, NULL); }
+static struct sst_machines sst_skl_devdata[] = { + { "INT343A", "skl_alc286s_i2s" }, +}; + /* PCI IDs */ static const struct pci_device_id skl_ids[] = { /* Sunrise Point-LP */ - { PCI_DEVICE(0x8086, 0x9d70), 0}, + { PCI_DEVICE(0x8086, 0x9d70), + .driver_data = (unsigned long)&sst_skl_devdata}, { 0, } }; MODULE_DEVICE_TABLE(pci, skl_ids); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index f803ebb10605..9b1beed26f0f 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -61,6 +61,7 @@ struct skl {
unsigned int init_failed:1; /* delayed init failed */ struct platform_device *dmic_dev; + struct platform_device *i2s_dev;
void *nhlt; /* nhlt ptr */ struct skl_sst *skl_sst; /* sst skl ctx */
The patch
ASoC: Intel: Skylake: Fix the SSP0 Fmt fixup to 24 bit
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 0b5a4831607f4d2c21f1779470d14253137050a3 Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Thu, 29 Oct 2015 12:31:34 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix the SSP0 Fmt fixup to 24 bit
SSP0 FMT uses 24 bits so fix to the value to 24 bits
Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/boards/skl_rt286.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index a73a431..e6af484 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -112,12 +112,15 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The output is 48KHz, stereo, 16bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+ /* set SSP0 to 24 bit */ + snd_mask_none(fmt); + snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); return 0; }
The patch
ASoC: Intel: Skylake: Fix PM behaviour
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 7d703efc69e704195073ed31963b2ca86c12194d Mon Sep 17 00:00:00 2001
From: Jeeja KP jeeja.kp@intel.com Date: Tue, 27 Oct 2015 09:23:00 +0900 Subject: [PATCH] ASoC: Intel: Skylake: Fix PM behaviour
The driver runtime behaviour is fine but in suspend, we missed setting the DSP to suspend and also missed resuming DSP on resume.
Fix this by having common SKL suspend and resume routines which power up/down links, suspend/resume DSP and other common routines, and call these routines from both runtime as well as system PM handlers
Signed-off-by: Jayachandran B jayachandran.b@intel.com Signed-off-by: Jeeja KP jeeja.kp@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl.c | 60 +++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 211ef6e2..9b94a8c 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -129,6 +129,37 @@ static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect) return 0; }
+#ifdef CONFIG_PM +static int _skl_suspend(struct hdac_ext_bus *ebus) +{ + struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = ebus_to_hbus(ebus); + int ret; + + snd_hdac_ext_bus_link_power_down_all(ebus); + + ret = skl_suspend_dsp(skl); + if (ret < 0) + return ret; + + snd_hdac_bus_stop_chip(bus); + snd_hdac_bus_enter_link_reset(bus); + + return 0; +} + +static int _skl_resume(struct hdac_ext_bus *ebus) +{ + struct skl *skl = ebus_to_skl(ebus); + struct hdac_bus *bus = ebus_to_hbus(ebus); + + skl_init_pci(skl); + snd_hdac_bus_init_chip(bus, true); + + return skl_resume_dsp(skl); +} +#endif + #ifdef CONFIG_PM_SLEEP /* * power management @@ -137,26 +168,16 @@ static int skl_suspend(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); - - snd_hdac_bus_stop_chip(bus); - snd_hdac_bus_enter_link_reset(bus);
- return 0; + return _skl_suspend(ebus); }
static int skl_resume(struct device *dev) { struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); - struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *hda = ebus_to_skl(ebus); - - skl_init_pci(hda);
- snd_hdac_bus_init_chip(bus, 1); - - return 0; + return _skl_resume(ebus); } #endif /* CONFIG_PM_SLEEP */
@@ -166,24 +187,13 @@ static int skl_runtime_suspend(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct hdac_ext_bus *ebus = pci_get_drvdata(pci); struct hdac_bus *bus = ebus_to_hbus(ebus); - struct skl *skl = ebus_to_skl(ebus); - int ret;
dev_dbg(bus->dev, "in %s\n", __func__);
/* enable controller wake up event */ snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
- snd_hdac_ext_bus_link_power_down_all(ebus); - - ret = skl_suspend_dsp(skl); - if (ret < 0) - return ret; - - snd_hdac_bus_stop_chip(bus); - snd_hdac_bus_enter_link_reset(bus); - - return 0; + return _skl_suspend(ebus); }
static int skl_runtime_resume(struct device *dev) @@ -204,7 +214,7 @@ static int skl_runtime_resume(struct device *dev) /* disable controller Wake Up event */ snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
- return skl_resume_dsp(skl); + return _skl_resume(ebus); } #endif /* CONFIG_PM */
On Tue, Oct 27, 2015 at 09:22:43AM +0900, Vinod Koul wrote:
Hi all,
This series adds more minor fixes and some enhancements to the driver. Most of the fixes patches are single line count changes
The enhancements are:
- optimizing code and using module pin info for unbinding
- supporting virtual dsp widgets like switches in topology
- add pin formats and supports multiple heterogeneous pins
Hi Mark,
Jeeja found two more fixes for this so I have appended these to the last patch. First fixes bit format on SSP port and second fixes the missing machine entry required as BIOS doesn't have that
They seem to appear in this thread so easy to find :)
On Thu, Oct 29, 2015 at 12:34:37PM +0900, Vinod Koul wrote:
Jeeja found two more fixes for this so I have appended these to the last patch. First fixes bit format on SSP port and second fixes the missing machine entry required as BIOS doesn't have that
They seem to appear in this thread so easy to find :)
Please don't send new patches as followups to something in the middle of a series, it creates confusion trying to understand what the current version of the series is intended to be. Please resend whatever you want applying as a separate series.
On Fri, Oct 30, 2015 at 09:50:25AM +0900, Mark Brown wrote:
On Thu, Oct 29, 2015 at 12:34:37PM +0900, Vinod Koul wrote:
Jeeja found two more fixes for this so I have appended these to the last patch. First fixes bit format on SSP port and second fixes the missing machine entry required as BIOS doesn't have that
They seem to appear in this thread so easy to find :)
Please don't send new patches as followups to something in the middle of a series, it creates confusion trying to understand what the current version of the series is intended to be. Please resend whatever you want applying as a separate series.
Okay will resend now. Since they were dependent I though way to ensure that was to append to this one...
Thanks
participants (2)
-
Mark Brown
-
Vinod Koul