summaryrefslogtreecommitdiff
path: root/sound/soc/intel/skylake
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-05 10:42:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-05 10:42:07 -0700
commite02d37bf55a9a36f22427fd6dd733fe104d817b6 (patch)
treef22c545ac3eec3e919db1c5e423d83aa7f3536be /sound/soc/intel/skylake
parent652ede37cec0bf7313927ecf4cebf0e79a0619f2 (diff)
parenta820ccbe21e8ce8e86c39cd1d3bc8c7d1cbb949b (diff)
Merge tag 'sound-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This became a large update. The changes are scattered widely, and the majority of them are attributed to ASoC componentization. The gitk output made me dizzy, but it's slightly better than London tube. OK, below are some highlights: - Continued hardening works in ALSA PCM core; most of the existing syzkaller reports should have been covered. - USB-audio got the initial USB Audio Class 3 support, as well as UAC2 jack detection support and more DSD-device support. - ASoC componentization: finally each individual driver was converted to components framework, which is more future-proof for further works. Most of conversations were systematic. - Lots of fixes for Intel Baytrail / Cherrytrail devices with Realtek codecs, typically tablets and small PCs. - Fixes / cleanups for Samsung Odroid systems - Cleanups in Freescale SSI driver - New ASoC drivers: * AKM AK4458 and AK5558 codecs * A few AMD based machine drivers * Intel Kabylake machine drivers * Maxim MAX9759 codec * Motorola CPCAP codec * Socionext Uniphier SoCs * TI PCM1789 and TDA7419 codecs - Retirement of Blackfin drivers along with architecture removal" * tag 'sound-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (497 commits) ALSA: pcm: Fix UAF at PCM release via PCM timer access ALSA: usb-audio: silence a static checker warning ASoC: tscs42xx: Remove owner assignment from i2c_driver ASoC: mediatek: remove "simple-mfd" in the example ASoC: cpcap: replace codec to component ASoC: Intel: bytcr_rt5651: don't use codec anymore ASoC: amd: don't use codec anymore ALSA: usb-audio: fix memory leak on cval ALSA: pcm: Fix mutex unbalance in OSS emulation ioctls ASoC: topology: Fix kcontrol name string handling ALSA: aloop: Mark paused device as inactive ALSA: usb-audio: update clock valid control ALSA: usb-audio: UAC2 jack detection ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams ALSA: pcm: Avoid potential races between OSS ioctls and read/write ALSA: usb-audio: Integrate native DSD support for ITF-USB based DACs. ALSA: usb-audio: FIX native DSD support for TEAC UD-501 DAC ALSA: usb-audio: Add native DSD support for Luxman DA-06 ALSA: usb-audio: fix uac control query argument ASoC: nau8824: recover system clock when device changes ...
Diffstat (limited to 'sound/soc/intel/skylake')
-rw-r--r--sound/soc/intel/skylake/skl-debug.c2
-rw-r--r--sound/soc/intel/skylake/skl-messages.c9
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c72
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c4
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h3
-rw-r--r--sound/soc/intel/skylake/skl-topology.c133
-rw-r--r--sound/soc/intel/skylake/skl-topology.h15
-rw-r--r--sound/soc/intel/skylake/skl.c40
-rw-r--r--sound/soc/intel/skylake/skl.h6
9 files changed, 217 insertions, 67 deletions
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index dc20d91f62e6..a016455a6ddb 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -231,7 +231,7 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
/* create the debugfs dir with platform component's debugfs as parent */
d->fs = debugfs_create_dir("dsp",
- skl->platform->component.debugfs_root);
+ skl->component->debugfs_root);
if (IS_ERR(d->fs) || !d->fs) {
dev_err(&skl->pci->dev, "debugfs root creation failed\n");
return NULL;
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 60d76adade43..57d4a58522a6 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -417,11 +417,16 @@ int skl_resume_dsp(struct skl *skl)
if (skl->skl_sst->is_first_boot == true)
return 0;
- /* disable dynamic clock gating during fw and lib download */
+ /*
+ * Disable dynamic clock and power gating during firmware
+ * and library download
+ */
ctx->enable_miscbdcge(ctx->dev, false);
+ ctx->clock_power_gating(ctx->dev, false);
ret = skl_dsp_wake(ctx->dsp);
ctx->enable_miscbdcge(ctx->dev, true);
+ ctx->clock_power_gating(ctx->dev, true);
if (ret < 0)
return ret;
@@ -1210,7 +1215,7 @@ out:
static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
enum skl_ipc_pipeline_state state)
{
- dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state);
+ dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state);
return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index e46828533826..15cb8ac3e374 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -959,6 +959,17 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
},
},
{
+ .name = "DMIC16k Pin",
+ .ops = &skl_dmic_dai_ops,
+ .capture = {
+ .stream_name = "DMIC16k Rx",
+ .channels_min = HDA_MONO,
+ .channels_max = HDA_QUAD,
+ .rates = SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+},
+{
.name = "HD-Codec Pin",
.ops = &skl_link_dai_ops,
.playback = {
@@ -1307,29 +1318,31 @@ static int skl_populate_modules(struct skl *skl)
"query module info failed\n");
return ret;
}
+
+ skl_tplg_add_moduleid_in_bind_params(skl, w);
}
}
return ret;
}
-static int skl_platform_soc_probe(struct snd_soc_platform *platform)
+static int skl_platform_soc_probe(struct snd_soc_component *component)
{
- struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
+ struct hdac_ext_bus *ebus = dev_get_drvdata(component->dev);
struct skl *skl = ebus_to_skl(ebus);
const struct skl_dsp_ops *ops;
int ret;
- pm_runtime_get_sync(platform->dev);
+ pm_runtime_get_sync(component->dev);
if ((ebus_to_hbus(ebus))->ppcap) {
- skl->platform = platform;
+ skl->component = component;
/* init debugfs */
skl->debugfs = skl_debugfs_init(skl);
- ret = skl_tplg_init(platform, ebus);
+ ret = skl_tplg_init(component, ebus);
if (ret < 0) {
- dev_err(platform->dev, "Failed to init topology!\n");
+ dev_err(component->dev, "Failed to init topology!\n");
return ret;
}
@@ -1339,17 +1352,22 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
return -EIO;
if (skl->skl_sst->is_first_boot == false) {
- dev_err(platform->dev, "DSP reports first boot done!!!\n");
+ dev_err(component->dev, "DSP reports first boot done!!!\n");
return -EIO;
}
- /* disable dynamic clock gating during fw and lib download */
- skl->skl_sst->enable_miscbdcge(platform->dev, false);
+ /*
+ * Disable dynamic clock and power gating during firmware
+ * and library download
+ */
+ skl->skl_sst->enable_miscbdcge(component->dev, false);
+ skl->skl_sst->clock_power_gating(component->dev, false);
- ret = ops->init_fw(platform->dev, skl->skl_sst);
- skl->skl_sst->enable_miscbdcge(platform->dev, true);
+ ret = ops->init_fw(component->dev, skl->skl_sst);
+ skl->skl_sst->enable_miscbdcge(component->dev, true);
+ skl->skl_sst->clock_power_gating(component->dev, true);
if (ret < 0) {
- dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
+ dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
return ret;
}
skl_populate_modules(skl);
@@ -1362,22 +1380,20 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
skl->cfg.astate_cfg);
}
}
- pm_runtime_mark_last_busy(platform->dev);
- pm_runtime_put_autosuspend(platform->dev);
+ pm_runtime_mark_last_busy(component->dev);
+ pm_runtime_put_autosuspend(component->dev);
return 0;
}
-static const struct snd_soc_platform_driver skl_platform_drv = {
+
+static const struct snd_soc_component_driver skl_component = {
+ .name = "pcm",
.probe = skl_platform_soc_probe,
.ops = &skl_platform_ops,
.pcm_new = skl_pcm_new,
.pcm_free = skl_pcm_free,
};
-static const struct snd_soc_component_driver skl_component = {
- .name = "pcm",
-};
-
int skl_platform_register(struct device *dev)
{
int ret;
@@ -1389,12 +1405,6 @@ int skl_platform_register(struct device *dev)
INIT_LIST_HEAD(&skl->ppl_list);
INIT_LIST_HEAD(&skl->bind_list);
- ret = snd_soc_register_platform(dev, &skl_platform_drv);
- if (ret) {
- dev_err(dev, "soc platform registration failed %d\n", ret);
- return ret;
- }
-
skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
GFP_KERNEL);
if (!skl->dais) {
@@ -1416,18 +1426,12 @@ int skl_platform_register(struct device *dev)
num_dais += ARRAY_SIZE(skl_fe_dai);
}
- ret = snd_soc_register_component(dev, &skl_component,
+ ret = devm_snd_soc_register_component(dev, &skl_component,
skl->dais, num_dais);
- if (ret) {
+ if (ret)
dev_err(dev, "soc component registration failed %d\n", ret);
- goto err;
- }
-
- return 0;
err:
- snd_soc_unregister_platform(dev);
return ret;
-
}
int skl_platform_unregister(struct device *dev)
@@ -1443,8 +1447,6 @@ int skl_platform_unregister(struct device *dev)
}
}
- snd_soc_unregister_component(dev);
- snd_soc_unregister_platform(dev);
kfree(skl->dais);
return 0;
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
index 7fbddf5e3b00..cda1b5fa7436 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -247,8 +247,8 @@ static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
}
/* Not supported by clk driver. Implemented to satisfy clk fw */
-long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
{
return rate;
}
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 55f2d2ce09df..f74f040dfd83 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -118,6 +118,9 @@ struct skl_sst {
struct skl_d0i3_data d0i3;
const struct skl_dsp_ops *dsp_ops;
+
+ /* Callback to update dynamic clock and power gating registers */
+ void (*clock_power_gating)(struct device *dev, bool enable);
};
struct skl_ipc_init_instance_msg {
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 73af6e19ebbd..3b1dca419883 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -94,8 +94,12 @@ void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
* SKL DSP driver modelling uses only few DAPM widgets so for rest we will
* ignore. This helpers checks if the SKL driver handles this widget type
*/
-static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
+static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
+ struct device *dev)
{
+ if (w->dapm->dev != dev)
+ return false;
+
switch (w->id) {
case snd_soc_dapm_dai_link:
case snd_soc_dapm_dai_in:
@@ -826,7 +830,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
struct skl_kpb_params *kpb_params =
(struct skl_kpb_params *)params;
- struct skl_mod_inst_map *inst = kpb_params->map;
+ struct skl_mod_inst_map *inst = kpb_params->u.map;
for (i = 0; i < kpb_params->num_modules; i++) {
pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
@@ -911,6 +915,87 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
return 0;
}
+static int skl_get_module_id(struct skl_sst *ctx, uuid_le *uuid)
+{
+ struct uuid_module *module;
+
+ list_for_each_entry(module, &ctx->uuid_list, list) {
+ if (uuid_le_cmp(*uuid, module->uuid) == 0)
+ return module->id;
+ }
+
+ return -EINVAL;
+}
+
+static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
+ const struct snd_kcontrol_new *k)
+{
+ struct soc_bytes_ext *sb = (void *) k->private_value;
+ struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
+ struct skl_kpb_params *uuid_params, *params;
+ struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl));
+ int i, size, module_id;
+
+ if (bc->set_params == SKL_PARAM_BIND && bc->max) {
+ uuid_params = (struct skl_kpb_params *)bc->params;
+ size = uuid_params->num_modules *
+ sizeof(struct skl_mod_inst_map) +
+ sizeof(uuid_params->num_modules);
+
+ params = devm_kzalloc(bus->dev, size, GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+
+ params->num_modules = uuid_params->num_modules;
+
+ for (i = 0; i < uuid_params->num_modules; i++) {
+ module_id = skl_get_module_id(skl->skl_sst,
+ &uuid_params->u.map_uuid[i].mod_uuid);
+ if (module_id < 0) {
+ devm_kfree(bus->dev, params);
+ return -EINVAL;
+ }
+
+ params->u.map[i].mod_id = module_id;
+ params->u.map[i].inst_id =
+ uuid_params->u.map_uuid[i].inst_id;
+ }
+
+ devm_kfree(bus->dev, bc->params);
+ bc->params = (char *)params;
+ bc->max = size;
+ }
+
+ return 0;
+}
+
+/*
+ * Retrieve the module id from UUID mentioned in the
+ * post bind params
+ */
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+ struct snd_soc_dapm_widget *w)
+{
+ struct skl_module_cfg *mconfig = w->priv;
+ int i;
+
+ /*
+ * Post bind params are used for only for KPB
+ * to set copier instances to drain the data
+ * in fast mode
+ */
+ if (mconfig->m_type != SKL_MODULE_TYPE_KPB)
+ return;
+
+ for (i = 0; i < w->num_kcontrols; i++)
+ if ((w->kcontrol_news[i].access &
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
+ (skl_tplg_find_moduleid_from_uuid(skl,
+ &w->kcontrol_news[i]) < 0))
+ dev_err(skl->skl_sst->dev,
+ "%s: invalid kpb post bind params\n",
+ __func__);
+}
static int skl_tplg_module_add_deferred_bind(struct skl *skl,
struct skl_module_cfg *src, struct skl_module_cfg *dst)
@@ -969,7 +1054,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
next_sink = p->sink;
- if (!is_skl_dsp_widget_type(p->sink))
+ if (!is_skl_dsp_widget_type(p->sink, ctx->dev))
return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
/*
@@ -978,7 +1063,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
* they are ones used for SKL so check that first
*/
if ((p->sink->priv != NULL) &&
- is_skl_dsp_widget_type(p->sink)) {
+ is_skl_dsp_widget_type(p->sink, ctx->dev)) {
sink = p->sink;
sink_mconfig = sink->priv;
@@ -1092,7 +1177,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
* ones used for SKL so check that first
*/
if ((p->source->priv != NULL) &&
- is_skl_dsp_widget_type(p->source)) {
+ is_skl_dsp_widget_type(p->source, ctx->dev)) {
return p->source;
}
}
@@ -1654,7 +1739,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, dai->dev))
continue;
if (p->sink->priv) {
@@ -1667,7 +1752,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, dai->dev))
continue;
if (p->source->priv) {
@@ -1819,7 +1904,7 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
int ret = -EIO;
snd_soc_dapm_widget_for_each_source_path(w, p) {
- if (p->connect && is_skl_dsp_widget_type(p->source) &&
+ if (p->connect && is_skl_dsp_widget_type(p->source, dai->dev) &&
p->source->priv) {
ret = skl_tplg_be_fill_pipe_params(dai,
@@ -1844,7 +1929,7 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
int ret = -EIO;
snd_soc_dapm_widget_for_each_sink_path(w, p) {
- if (p->connect && is_skl_dsp_widget_type(p->sink) &&
+ if (p->connect && is_skl_dsp_widget_type(p->sink, dai->dev) &&
p->sink->priv) {
ret = skl_tplg_be_fill_pipe_params(dai,
@@ -2710,15 +2795,15 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
return 0;
}
-static void skl_clear_pin_config(struct snd_soc_platform *platform,
+static void skl_clear_pin_config(struct snd_soc_component *component,
struct snd_soc_dapm_widget *w)
{
int i;
struct skl_module_cfg *mconfig;
struct skl_pipe *pipe;
- if (!strncmp(w->dapm->component->name, platform->component.name,
- strlen(platform->component.name))) {
+ if (!strncmp(w->dapm->component->name, component->name,
+ strlen(component->name))) {
mconfig = w->priv;
pipe = mconfig->pipe;
for (i = 0; i < mconfig->module->max_input_pins; i++) {
@@ -2737,14 +2822,14 @@ static void skl_clear_pin_config(struct snd_soc_platform *platform,
void skl_cleanup_resources(struct skl *skl)
{
struct skl_sst *ctx = skl->skl_sst;
- struct snd_soc_platform *soc_platform = skl->platform;
+ struct snd_soc_component *soc_component = skl->component;
struct snd_soc_dapm_widget *w;
struct snd_soc_card *card;
- if (soc_platform == NULL)
+ if (soc_component == NULL)
return;
- card = soc_platform->component.card;
+ card = soc_component->card;
if (!card || !card->instantiated)
return;
@@ -2752,8 +2837,8 @@ void skl_cleanup_resources(struct skl *skl)
skl->resource.mcps = 0;
list_for_each_entry(w, &card->widgets, list) {
- if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
- skl_clear_pin_config(soc_platform, w);
+ if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL)
+ skl_clear_pin_config(soc_component, w);
}
skl_clear_module_cnt(ctx->dsp);
@@ -3400,19 +3485,19 @@ static struct snd_soc_tplg_ops skl_tplg_ops = {
* widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
* helps to get the SKL type widgets in that pipeline
*/
-static int skl_tplg_create_pipe_widget_list(struct snd_soc_platform *platform)
+static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
{
struct snd_soc_dapm_widget *w;
struct skl_module_cfg *mcfg = NULL;
struct skl_pipe_module *p_module = NULL;
struct skl_pipe *pipe;
- list_for_each_entry(w, &platform->component.card->widgets, list) {
- if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
+ list_for_each_entry(w, &component->card->widgets, list) {
+ if (is_skl_dsp_widget_type(w, component->dev) && w->priv) {
mcfg = w->priv;
pipe = mcfg->pipe;
- p_module = devm_kzalloc(platform->dev,
+ p_module = devm_kzalloc(component->dev,
sizeof(*p_module), GFP_KERNEL);
if (!p_module)
return -ENOMEM;
@@ -3455,7 +3540,7 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
/*
* SKL topology init routine
*/
-int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
+int skl_tplg_init(struct snd_soc_component *component, struct hdac_ext_bus *ebus)
{
int ret;
const struct firmware *fw;
@@ -3479,7 +3564,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
* The complete tplg for SKL is loaded as index 0, we don't use
* any other index
*/
- ret = snd_soc_tplg_component_load(&platform->component,
+ ret = snd_soc_tplg_component_load(component,
&skl_tplg_ops, fw, 0);
if (ret < 0) {
dev_err(bus->dev, "tplg component load failed%d\n", ret);
@@ -3491,7 +3576,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
skl->resource.max_mem = SKL_FW_MAX_MEM;
skl->tplg = fw;
- ret = skl_tplg_create_pipe_widget_list(platform);
+ ret = skl_tplg_create_pipe_widget_list(component);
if (ret < 0)
return ret;
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index b6496513fe55..b1e0667c0ae0 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -221,9 +221,18 @@ struct skl_mod_inst_map {
u16 inst_id;
};
+struct skl_uuid_inst_map {
+ u16 inst_id;
+ u16 reserved;
+ uuid_le mod_uuid;
+} __packed;
+
struct skl_kpb_params {
u32 num_modules;
- struct skl_mod_inst_map map[0];
+ union {
+ struct skl_mod_inst_map map[0];
+ struct skl_uuid_inst_map map_uuid[0];
+ } u;
};
struct skl_module_inst_id {
@@ -460,7 +469,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
u32 caps_size, u32 node_id);
void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
struct skl_pipe_params *params, int stream);
-int skl_tplg_init(struct snd_soc_platform *platform,
+int skl_tplg_init(struct snd_soc_component *component,
struct hdac_ext_bus *ebus);
struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
struct snd_soc_dai *dai, int stream);
@@ -505,4 +514,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
int skl_dai_load(struct snd_soc_component *cmp,
struct snd_soc_dai_driver *pcm_dai);
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+ struct snd_soc_dapm_widget *w);
#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 32ce64c6b2dc..abf324747b29 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -94,6 +94,32 @@ static void skl_enable_miscbdcge(struct device *dev, bool enable)
update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
}
+/**
+ * skl_clock_power_gating: Enable/Disable clock and power gating
+ *
+ * @dev: Device pointer
+ * @enable: Enable/Disable flag
+ */
+static void skl_clock_power_gating(struct device *dev, bool enable)
+{
+ 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);
+ u32 val;
+
+ /* Update PDCGE bit of CGCTL register */
+ val = enable ? AZX_CGCTL_ADSPDCGE : 0;
+ update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_ADSPDCGE, val);
+
+ /* Update L1SEN bit of EM2 register */
+ val = enable ? AZX_REG_VS_EM2_L1SEN : 0;
+ snd_hdac_chip_updatel(bus, VS_EM2, AZX_REG_VS_EM2_L1SEN, val);
+
+ /* Update ADSPPGD bit of PGCTL register */
+ val = enable ? 0 : AZX_PGCTL_ADSPPGD;
+ update_pci_dword(pci, AZX_PCIREG_PGCTL, AZX_PGCTL_ADSPPGD, val);
+}
+
/*
* While performing reset, controller may not come back properly causing
* issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
@@ -916,6 +942,7 @@ static int skl_probe(struct pci_dev *pci,
goto out_nhlt_free;
}
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
+ skl->skl_sst->clock_power_gating = skl_clock_power_gating;
}
if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(ebus);
@@ -1017,6 +1044,11 @@ static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
.codecs = {"10EC5663", "10EC5514"}
};
+static struct snd_soc_acpi_codecs kbl_7219_98357_codecs = {
+ .num_codecs = 1,
+ .codecs = {"MX98357A"}
+};
+
static struct skl_machine_pdata cnl_pdata = {
.use_tplg_pcm = true,
};
@@ -1105,6 +1137,14 @@ static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
.drv_name = "kbl_rt5663",
.fw_filename = "intel/dsp_fw_kbl.bin",
},
+ {
+ .id = "DLGS7219",
+ .drv_name = "kbl_da7219_max98357a",
+ .fw_filename = "intel/dsp_fw_kbl.bin",
+ .machine_quirk = snd_soc_acpi_codec_list,
+ .quirk_data = &kbl_7219_98357_codecs,
+ .pdata = &skl_dmic_data
+ },
{}
};
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 2d13f3fd988a..0d5375cbcf6e 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -33,8 +33,10 @@
#define AZX_PCIREG_PGCTL 0x44
#define AZX_PGCTL_LSRMD_MASK (1 << 4)
+#define AZX_PGCTL_ADSPPGD BIT(2)
#define AZX_PCIREG_CGCTL 0x48
#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
+#define AZX_CGCTL_ADSPDCGE BIT(1)
/* D0I3C Register fields */
#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
@@ -43,6 +45,8 @@
#define DMA_TRANSMITION_START 2
#define DMA_TRANSMITION_STOP 3
+#define AZX_REG_VS_EM2_L1SEN BIT(13)
+
struct skl_dsp_resource {
u32 max_mcps;
u32 max_mem;
@@ -74,7 +78,7 @@ struct skl {
struct platform_device *dmic_dev;
struct platform_device *i2s_dev;
struct platform_device *clk_dev;
- struct snd_soc_platform *platform;
+ struct snd_soc_component *component;
struct snd_soc_dai_driver *dais;
struct nhlt_acpi_table *nhlt; /* nhlt ptr */