forked from Minki/linux
Merge branch 'fix/intel' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-intel
This commit is contained in:
commit
98ab7a0204
@ -528,6 +528,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
|
|||||||
.ops = &sst_compr_dai_ops,
|
.ops = &sst_compr_dai_ops,
|
||||||
.playback = {
|
.playback = {
|
||||||
.stream_name = "Compress Playback",
|
.stream_name = "Compress Playback",
|
||||||
|
.channels_min = 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/* BE CPU Dais */
|
/* BE CPU Dais */
|
||||||
|
@ -212,7 +212,10 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
|
|||||||
{
|
{
|
||||||
struct snd_interval *channels = hw_param_interval(params,
|
struct snd_interval *channels = hw_param_interval(params,
|
||||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||||||
channels->min = channels->max = 4;
|
if (params_channels(params) == 2)
|
||||||
|
channels->min = channels->max = 2;
|
||||||
|
else
|
||||||
|
channels->min = channels->max = 4;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -688,14 +688,14 @@ int skl_unbind_modules(struct skl_sst *ctx,
|
|||||||
/* get src queue index */
|
/* get src queue index */
|
||||||
src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
|
src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
|
||||||
if (src_index < 0)
|
if (src_index < 0)
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
msg.src_queue = src_index;
|
msg.src_queue = src_index;
|
||||||
|
|
||||||
/* get dst queue index */
|
/* get dst queue index */
|
||||||
dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
|
dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
|
||||||
if (dst_index < 0)
|
if (dst_index < 0)
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
msg.dst_queue = dst_index;
|
msg.dst_queue = dst_index;
|
||||||
|
|
||||||
@ -747,7 +747,7 @@ int skl_bind_modules(struct skl_sst *ctx,
|
|||||||
|
|
||||||
skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
|
skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
|
||||||
|
|
||||||
if (src_mcfg->m_state < SKL_MODULE_INIT_DONE &&
|
if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
|
||||||
dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
|
dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -863,6 +863,7 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus,
|
|||||||
else
|
else
|
||||||
delay += hstream->bufsize;
|
delay += hstream->bufsize;
|
||||||
}
|
}
|
||||||
|
delay = (hstream->bufsize == delay) ? 0 : delay;
|
||||||
|
|
||||||
if (delay >= hstream->period_bytes) {
|
if (delay >= hstream->period_bytes) {
|
||||||
dev_info(bus->dev,
|
dev_info(bus->dev,
|
||||||
|
@ -54,12 +54,9 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Each pipelines needs memory to be allocated. Check if we have free memory
|
* Each pipelines needs memory to be allocated. Check if we have free memory
|
||||||
* from available pool. Then only add this to pool
|
* from available pool.
|
||||||
* This is freed when pipe is deleted
|
|
||||||
* Note: DSP does actual memory management we only keep track for complete
|
|
||||||
* pool
|
|
||||||
*/
|
*/
|
||||||
static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
|
static bool skl_is_pipe_mem_avail(struct skl *skl,
|
||||||
struct skl_module_cfg *mconfig)
|
struct skl_module_cfg *mconfig)
|
||||||
{
|
{
|
||||||
struct skl_sst *ctx = skl->skl_sst;
|
struct skl_sst *ctx = skl->skl_sst;
|
||||||
@ -74,10 +71,20 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
|
|||||||
"exceeds ppl memory available %d mem %d\n",
|
"exceeds ppl memory available %d mem %d\n",
|
||||||
skl->resource.max_mem, skl->resource.mem);
|
skl->resource.max_mem, skl->resource.mem);
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the mem to the mem pool. This is freed when pipe is deleted.
|
||||||
|
* Note: DSP does actual memory management we only keep track for complete
|
||||||
|
* pool
|
||||||
|
*/
|
||||||
|
static void skl_tplg_alloc_pipe_mem(struct skl *skl,
|
||||||
|
struct skl_module_cfg *mconfig)
|
||||||
|
{
|
||||||
skl->resource.mem += mconfig->pipe->memory_pages;
|
skl->resource.mem += mconfig->pipe->memory_pages;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -85,10 +92,10 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
|
|||||||
* quantified in MCPS (Million Clocks Per Second) required for module/pipe
|
* quantified in MCPS (Million Clocks Per Second) required for module/pipe
|
||||||
*
|
*
|
||||||
* Each pipelines needs mcps to be allocated. Check if we have mcps for this
|
* Each pipelines needs mcps to be allocated. Check if we have mcps for this
|
||||||
* pipe. This adds the mcps to driver counter
|
* pipe.
|
||||||
* This is removed on pipeline delete
|
|
||||||
*/
|
*/
|
||||||
static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
|
|
||||||
|
static bool skl_is_pipe_mcps_avail(struct skl *skl,
|
||||||
struct skl_module_cfg *mconfig)
|
struct skl_module_cfg *mconfig)
|
||||||
{
|
{
|
||||||
struct skl_sst *ctx = skl->skl_sst;
|
struct skl_sst *ctx = skl->skl_sst;
|
||||||
@ -98,13 +105,18 @@ static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
|
|||||||
"%s: module_id %d instance %d\n", __func__,
|
"%s: module_id %d instance %d\n", __func__,
|
||||||
mconfig->id.module_id, mconfig->id.instance_id);
|
mconfig->id.module_id, mconfig->id.instance_id);
|
||||||
dev_err(ctx->dev,
|
dev_err(ctx->dev,
|
||||||
"exceeds ppl memory available %d > mem %d\n",
|
"exceeds ppl mcps available %d > mem %d\n",
|
||||||
skl->resource.max_mcps, skl->resource.mcps);
|
skl->resource.max_mcps, skl->resource.mcps);
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skl_tplg_alloc_pipe_mcps(struct skl *skl,
|
||||||
|
struct skl_module_cfg *mconfig)
|
||||||
|
{
|
||||||
skl->resource.mcps += mconfig->mcps;
|
skl->resource.mcps += mconfig->mcps;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -411,7 +423,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
|
|||||||
mconfig = w->priv;
|
mconfig = w->priv;
|
||||||
|
|
||||||
/* check resource available */
|
/* check resource available */
|
||||||
if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
|
if (!skl_is_pipe_mcps_avail(skl, mconfig))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
|
if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
|
||||||
@ -435,6 +447,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
|
|||||||
ret = skl_tplg_set_module_params(w, ctx);
|
ret = skl_tplg_set_module_params(w, ctx);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
skl_tplg_alloc_pipe_mcps(skl, mconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -477,10 +490,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
|
|||||||
struct skl_sst *ctx = skl->skl_sst;
|
struct skl_sst *ctx = skl->skl_sst;
|
||||||
|
|
||||||
/* check resource available */
|
/* check resource available */
|
||||||
if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
|
if (!skl_is_pipe_mcps_avail(skl, mconfig))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (!skl_tplg_alloc_pipe_mem(skl, mconfig))
|
if (!skl_is_pipe_mem_avail(skl, mconfig))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -526,11 +539,15 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
|
|||||||
src_module = dst_module;
|
src_module = dst_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skl_tplg_alloc_pipe_mem(skl, mconfig);
|
||||||
|
skl_tplg_alloc_pipe_mcps(skl, mconfig);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
||||||
struct skl *skl,
|
struct skl *skl,
|
||||||
|
struct snd_soc_dapm_widget *src_w,
|
||||||
struct skl_module_cfg *src_mconfig)
|
struct skl_module_cfg *src_mconfig)
|
||||||
{
|
{
|
||||||
struct snd_soc_dapm_path *p;
|
struct snd_soc_dapm_path *p;
|
||||||
@ -547,6 +564,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
|||||||
dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
|
dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
|
||||||
|
|
||||||
next_sink = p->sink;
|
next_sink = p->sink;
|
||||||
|
|
||||||
|
if (!is_skl_dsp_widget_type(p->sink))
|
||||||
|
return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here we will check widgets in sink pipelines, so that
|
* here we will check widgets in sink pipelines, so that
|
||||||
* can be any widgets type and we are only interested if
|
* can be any widgets type and we are only interested if
|
||||||
@ -576,7 +597,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sink)
|
if (!sink)
|
||||||
return skl_tplg_bind_sinks(next_sink, skl, src_mconfig);
|
return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -605,7 +626,7 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
|
|||||||
* if sink is not started, start sink pipe first, then start
|
* if sink is not started, start sink pipe first, then start
|
||||||
* this pipe
|
* this pipe
|
||||||
*/
|
*/
|
||||||
ret = skl_tplg_bind_sinks(w, skl, src_mconfig);
|
ret = skl_tplg_bind_sinks(w, skl, w, src_mconfig);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -773,10 +794,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = skl_unbind_modules(ctx, src_module, dst_module);
|
skl_unbind_modules(ctx, src_module, dst_module);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
src_module = dst_module;
|
src_module = dst_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -814,9 +832,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
|
|||||||
* This is a connecter and if path is found that means
|
* This is a connecter and if path is found that means
|
||||||
* unbind between source and sink has not happened yet
|
* 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,
|
ret = skl_unbind_modules(ctx, src_mconfig,
|
||||||
sink_mconfig);
|
sink_mconfig);
|
||||||
}
|
}
|
||||||
@ -842,6 +857,12 @@ static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
|
|||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
|
return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
|
||||||
|
|
||||||
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
|
return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
|
||||||
|
|
||||||
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
|
return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
|
||||||
|
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
|
return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
|
||||||
}
|
}
|
||||||
@ -916,6 +937,13 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
|
|||||||
skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
|
skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
|
||||||
bc->max, bc->param_id, mconfig);
|
bc->max, bc->param_id, mconfig);
|
||||||
|
|
||||||
|
/* decrement size for TLV header */
|
||||||
|
size -= 2 * sizeof(u32);
|
||||||
|
|
||||||
|
/* check size as we don't want to send kernel data */
|
||||||
|
if (size > bc->max)
|
||||||
|
size = bc->max;
|
||||||
|
|
||||||
if (bc->params) {
|
if (bc->params) {
|
||||||
if (copy_to_user(data, &bc->param_id, sizeof(u32)))
|
if (copy_to_user(data, &bc->param_id, sizeof(u32)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -1510,6 +1538,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
|
|||||||
&skl_tplg_ops, fw, 0);
|
&skl_tplg_ops, fw, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(bus->dev, "tplg component load failed%d\n", ret);
|
dev_err(bus->dev, "tplg component load failed%d\n", ret);
|
||||||
|
release_firmware(fw);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,8 +614,6 @@ static int skl_probe(struct pci_dev *pci,
|
|||||||
goto out_unregister;
|
goto out_unregister;
|
||||||
|
|
||||||
/*configure PM */
|
/*configure PM */
|
||||||
pm_runtime_set_autosuspend_delay(bus->dev, SKL_SUSPEND_DELAY);
|
|
||||||
pm_runtime_use_autosuspend(bus->dev);
|
|
||||||
pm_runtime_put_noidle(bus->dev);
|
pm_runtime_put_noidle(bus->dev);
|
||||||
pm_runtime_allow(bus->dev);
|
pm_runtime_allow(bus->dev);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user