@@ -36,9 +36,49 @@ int sof_intel_board_card_late_probe(struct snd_soc_card *card)
}
EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS);
+/*
+ * DMIC DAI Link
+ */
+static const struct snd_soc_dapm_widget dmic_widgets[] = {
+ SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_route dmic_routes[] = {
+ {"DMic", NULL, "SoC DMIC"},
+};
+
+static int dmic_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
+ ARRAY_SIZE(dmic_widgets));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes,
+ ARRAY_SIZE(dmic_routes));
+ if (ret) {
+ dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* DAI Link Helpers
*/
+static struct snd_soc_dai_link_component dmic_component[] = {
+ {
+ .name = "dmic-codec",
+ .dai_name = "dmic-hifi",
+ }
+};
+
static struct snd_soc_dai_link_component platform_component[] = {
{
/* name might be overridden during probe */
@@ -46,6 +86,58 @@ static struct snd_soc_dai_link_component platform_component[] = {
}
};
+int sof_intel_board_set_dmic_link(struct device *dev,
+ struct snd_soc_dai_link *link, int be_id,
+ enum sof_dmic_be_type be_type)
+{
+ struct snd_soc_dai_link_component *cpus;
+
+ /* cpus */
+ cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
+ GFP_KERNEL);
+ if (!cpus)
+ return -ENOMEM;
+
+ switch (be_type) {
+ case SOF_DMIC_01:
+ dev_dbg(dev, "link %d: dmic01\n", be_id);
+
+ link->name = "dmic01";
+ cpus->dai_name = "DMIC01 Pin";
+ break;
+ case SOF_DMIC_16K:
+ dev_dbg(dev, "link %d: dmic16k\n", be_id);
+
+ link->name = "dmic16k";
+ cpus->dai_name = "DMIC16k Pin";
+ break;
+ default:
+ dev_err(dev, "invalid be type %d\n", be_type);
+ return -EINVAL;
+ }
+
+ link->cpus = cpus;
+ link->num_cpus = 1;
+
+ /* codecs */
+ link->codecs = dmic_component;
+ link->num_codecs = ARRAY_SIZE(dmic_component);
+
+ /* platforms */
+ link->platforms = platform_component;
+ link->num_platforms = ARRAY_SIZE(platform_component);
+
+ link->id = be_id;
+ if (be_type == SOF_DMIC_01)
+ link->init = dmic_init;
+ link->ignore_suspend = 1;
+ link->no_pcm = 1;
+ link->dpcm_capture = 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(sof_intel_board_set_dmic_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
+
int sof_intel_board_set_intel_hdmi_link(struct device *dev,
struct snd_soc_dai_link *link, int be_id,
int hdmi_id, bool idisp_codec)
@@ -28,6 +28,7 @@ struct sof_rt5682_private {
* @hdmi: init data for hdmi dai link
* @codec_type: type of headset codec
* @amp_type: type of speaker amplifier
+ * @dmic_be_num: number of Intel PCH DMIC BE link
* @hdmi_num: number of Intel HDMI BE link
* @rt5682: private data for rt5682 machine driver
*/
@@ -38,6 +39,7 @@ struct sof_card_private {
enum sof_ssp_codec codec_type;
enum sof_ssp_codec amp_type;
+ int dmic_be_num;
int hdmi_num;
union {
@@ -45,8 +47,16 @@ struct sof_card_private {
};
};
+enum sof_dmic_be_type {
+ SOF_DMIC_01,
+ SOF_DMIC_16K,
+};
+
int sof_intel_board_card_late_probe(struct snd_soc_card *card);
+int sof_intel_board_set_dmic_link(struct device *dev,
+ struct snd_soc_dai_link *link, int be_id,
+ enum sof_dmic_be_type be_type);
int sof_intel_board_set_intel_hdmi_link(struct device *dev,
struct snd_soc_dai_link *link, int be_id,
int hdmi_id, bool idisp_codec);