clear-pkgs-linux-iot-lts2018/0346-ASoC-Intel-Skylake-Cre...

339 lines
9.9 KiB
Diff

From ad3cd1c9a6d69e85360cc496a3ef63444feaae19 Mon Sep 17 00:00:00 2001
From: "Diwakar, Praveen" <praveen.diwakar@intel.com>
Date: Tue, 6 Jun 2017 21:04:21 +0530
Subject: [PATCH 346/743] ASoC: Intel: Skylake: Create SSP BE dais dynamically
This patch creates BE SSP dai dynamically, by getting SSP
link information from NHLT.
Change-Id: I2b6e45125a3fbd1e7f155efe86b5fb1a983c0f41
Signed-off-by: Diwakar, Praveen <praveen.diwakar@intel.com>
Reviewed-on:
Reviewed-by: Kale, Sanyog R <sanyog.r.kale@intel.com>
Tested-by: Sm, Bhadur A <bhadur.a.sm@intel.com>
---
sound/soc/intel/skylake/skl-nhlt.c | 36 ++++++
sound/soc/intel/skylake/skl-pcm.c | 195 ++++++++++-------------------
sound/soc/intel/skylake/skl.h | 7 ++
3 files changed, 111 insertions(+), 127 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index b2873dd8cdf3..cf3d38136289 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -464,3 +464,39 @@ void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks)
epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
}
}
+
+static bool is_vbus_id_exist(struct skl *skl, int vbus_id)
+{
+ bool ret = false;
+ int i;
+
+ for (i = 0; i < skl->nhlt->endpoint_count; i++) {
+ if (vbus_id == skl->grp_cnt.vbus_id[i])
+ return true;
+ }
+ return ret;
+}
+
+/*
+ * This function gets endpoint count and vbus_id for the specific link type
+ * passed as parameter.
+ */
+void skl_nhlt_get_ep_cnt(struct skl *skl, int link_type)
+{
+ struct nhlt_endpoint *epnt = (struct nhlt_endpoint *) skl->nhlt->desc;
+ int i;
+
+ skl->grp_cnt.cnt = 0;
+ memset(skl->grp_cnt.vbus_id, 0xff,
+ (sizeof(int) * skl->nhlt->endpoint_count));
+
+ for (i = 0; i < skl->nhlt->endpoint_count; i++) {
+
+ if (epnt->linktype == link_type) {
+ if (!is_vbus_id_exist(skl, epnt->virtual_bus_id))
+ skl->grp_cnt.vbus_id[skl->grp_cnt.cnt++] =
+ epnt->virtual_bus_id;
+ }
+ epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
+ }
+}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index c1ddf5ce1852..96c912bafc87 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -1117,126 +1117,6 @@ static struct snd_soc_dai_driver skl_fe_dai[] = {
/* BE cpu dais and compress dais*/
static struct snd_soc_dai_driver skl_platform_dai[] = {
-{
- .name = "SSP0 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp0 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp0 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "SSP1 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp1 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp1 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "SSP2 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp2 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp2 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "SSP3 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp3 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp3 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "SSP4 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp4 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp4 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
-{
- .name = "SSP5 Pin",
- .ops = &skl_be_ssp_dai_ops,
- .playback = {
- .stream_name = "ssp5 Tx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
- .capture = {
- .stream_name = "ssp5 Rx",
- .channels_min = HDA_MONO,
- .channels_max = HDA_8_CH,
- .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S32_LE,
- },
-},
{
.name = "iDisp1 Pin",
.ops = &skl_link_dai_ops,
@@ -1994,40 +1874,101 @@ static const struct snd_soc_component_driver skl_component = {
.num_controls = ARRAY_SIZE(skl_controls),
};
+static struct snd_soc_dai_driver ssp_dai_info = {
+ .ops = &skl_be_ssp_dai_ops,
+ .playback = {
+ .channels_min = HDA_MONO,
+ .channels_max = HDA_8_CH,
+ .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .capture = {
+ .channels_min = HDA_MONO,
+ .channels_max = HDA_8_CH,
+ .rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ },
+};
+
int skl_platform_register(struct device *dev)
{
int ret;
- struct snd_soc_dai_driver *dais;
- int num_dais = ARRAY_SIZE(skl_platform_dai);
struct hdac_bus *bus = dev_get_drvdata(dev);
struct skl *skl = bus_to_skl(bus);
+ struct snd_soc_dai_driver *dais;
+ int num_dais = ARRAY_SIZE(skl_platform_dai);
+ int total_dais;
+ int i, index;
INIT_LIST_HEAD(&skl->ppl_list);
INIT_LIST_HEAD(&skl->bind_list);
skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
GFP_KERNEL);
+ skl->grp_cnt.vbus_id = devm_kcalloc(dev, skl->nhlt->endpoint_count,
+ sizeof(int), GFP_KERNEL);
+ if (!skl->grp_cnt.vbus_id)
+ return -ENOMEM;
+
+ skl_nhlt_get_ep_cnt(skl, NHLT_LINK_SSP);
+
+ total_dais = num_dais + skl->grp_cnt.cnt;
+
+ skl->dais = devm_kcalloc(dev, total_dais, sizeof(*dais), GFP_KERNEL);
+
if (!skl->dais) {
ret = -ENOMEM;
goto err;
}
+ memcpy(skl->dais, skl_platform_dai, sizeof(skl_platform_dai));
+
+ for (i = 0; i < skl->grp_cnt.cnt; i++) {
+ index = num_dais + i;
+
+ memcpy(&skl->dais[index], &ssp_dai_info, sizeof(ssp_dai_info));
+
+ skl->dais[index].name = kasprintf(GFP_KERNEL, "SSP%d Pin",
+ skl->grp_cnt.vbus_id[i]);
+ if (!skl->dais[index].name)
+ return -ENOMEM;
+
+ skl->dais[index].playback.stream_name = kasprintf(GFP_KERNEL,
+ "ssp%d Tx", skl->grp_cnt.vbus_id[i]);
+ if (!skl->dais[index].playback.stream_name) {
+ kfree(skl->dais[index].name);
+ return -ENOMEM;
+ }
+
+ skl->dais[index].capture.stream_name = kasprintf(GFP_KERNEL,
+ "ssp%d Rx", skl->grp_cnt.vbus_id[i]);
+ if (!skl->dais[index].capture.stream_name) {
+ kfree(skl->dais[index].name);
+ kfree(skl->dais[index].playback.stream_name);
+ return -ENOMEM;
+ }
+ }
+
if (!skl->use_tplg_pcm) {
- dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
- sizeof(skl_platform_dai), GFP_KERNEL);
+ total_dais += ARRAY_SIZE(skl_fe_dai);
+ dais = krealloc(skl->dais, (total_dais * sizeof(*dais)),
+ GFP_KERNEL);
if (!dais) {
ret = -ENOMEM;
goto err;
}
skl->dais = dais;
- memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai,
+ memcpy(&skl->dais[num_dais + skl->grp_cnt.cnt], skl_fe_dai,
sizeof(skl_fe_dai));
- num_dais += ARRAY_SIZE(skl_fe_dai);
+
+ num_dais = total_dais;
}
ret = devm_snd_soc_register_component(dev, &skl_component,
- skl->dais, num_dais);
+ skl->dais, total_dais);
if (ret)
dev_err(dev, "soc component registration failed %d\n", ret);
err:
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 01d54513b029..2883d86d56fe 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -71,6 +71,11 @@ struct skl_fw_config {
struct skl_astate_config *astate_cfg;
};
+struct ep_group_cnt {
+ int cnt;
+ int *vbus_id;
+};
+
struct skl {
struct hdac_bus hbus;
struct pci_dev *pci;
@@ -107,6 +112,7 @@ struct skl {
struct snd_soc_acpi_mach *mach;
bool nhlt_override;
bool mod_set_get_status;
+ struct ep_group_cnt grp_cnt;
};
#define skl_to_bus(s) (&(s)->hbus)
@@ -139,6 +145,7 @@ int skl_platform_unregister(struct device *dev);
int skl_platform_register(struct device *dev);
int skl_get_nhlt_version(struct device *dev);
+void skl_nhlt_get_ep_cnt(struct skl *skl, int link_type);
struct nhlt_acpi_table *skl_nhlt_init(struct device *dev);
void skl_nhlt_free(struct nhlt_acpi_table *addr);
struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
--
2.19.2