summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards/sof_board_helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards/sof_board_helpers.c')
-rw-r--r--sound/soc/intel/boards/sof_board_helpers.c146
1 files changed, 96 insertions, 50 deletions
diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c
index 088894ff4165..a5135be94f32 100644
--- a/sound/soc/intel/boards/sof_board_helpers.c
+++ b/sound/soc/intel/boards/sof_board_helpers.c
@@ -74,6 +74,11 @@ static int dmic_init(struct snd_soc_pcm_runtime *rtd)
* DAI Link Helpers
*/
+enum sof_dmic_be_type {
+ SOF_DMIC_01,
+ SOF_DMIC_16K,
+};
+
/* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */
#define DEFAULT_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_CODEC, \
SOF_LINK_DMIC01, \
@@ -97,13 +102,13 @@ static struct snd_soc_dai_link_component platform_component[] = {
}
};
-int sof_intel_board_set_codec_link(struct device *dev,
- struct snd_soc_dai_link *link, int be_id,
- enum sof_ssp_codec codec_type, int ssp_codec)
+static int set_ssp_codec_link(struct device *dev, struct snd_soc_dai_link *link,
+ int be_id, enum sof_ssp_codec codec_type,
+ int ssp_codec)
{
struct snd_soc_dai_link_component *cpus;
- dev_dbg(dev, "link %d: codec %s, ssp %d\n", be_id,
+ dev_dbg(dev, "link %d: ssp codec %s, ssp %d\n", be_id,
sof_ssp_get_codec_name(codec_type), ssp_codec);
/* link name */
@@ -144,11 +149,9 @@ int sof_intel_board_set_codec_link(struct device *dev,
return 0;
}
-EXPORT_SYMBOL_NS(sof_intel_board_set_codec_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
-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)
+static int 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;
@@ -196,16 +199,14 @@ int sof_intel_board_set_dmic_link(struct device *dev,
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)
+static int set_idisp_hdmi_link(struct device *dev, struct snd_soc_dai_link *link,
+ int be_id, int hdmi_id, bool idisp_codec)
{
struct snd_soc_dai_link_component *cpus, *codecs;
- dev_dbg(dev, "link %d: intel hdmi, hdmi id %d, idisp codec %d\n",
- be_id, hdmi_id, idisp_codec);
+ dev_dbg(dev, "link %d: idisp hdmi %d, idisp codec %d\n", be_id, hdmi_id,
+ idisp_codec);
/* link name */
link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id);
@@ -256,11 +257,9 @@ int sof_intel_board_set_intel_hdmi_link(struct device *dev,
return 0;
}
-EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
-int sof_intel_board_set_ssp_amp_link(struct device *dev,
- struct snd_soc_dai_link *link, int be_id,
- enum sof_ssp_codec amp_type, int ssp_amp)
+static int set_ssp_amp_link(struct device *dev, struct snd_soc_dai_link *link,
+ int be_id, enum sof_ssp_codec amp_type, int ssp_amp)
{
struct snd_soc_dai_link_component *cpus;
@@ -298,11 +297,9 @@ int sof_intel_board_set_ssp_amp_link(struct device *dev,
return 0;
}
-EXPORT_SYMBOL_NS(sof_intel_board_set_ssp_amp_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
-int sof_intel_board_set_bt_link(struct device *dev,
- struct snd_soc_dai_link *link, int be_id,
- int ssp_bt)
+static int set_bt_offload_link(struct device *dev, struct snd_soc_dai_link *link,
+ int be_id, int ssp_bt)
{
struct snd_soc_dai_link_component *cpus;
@@ -341,11 +338,9 @@ int sof_intel_board_set_bt_link(struct device *dev,
return 0;
}
-EXPORT_SYMBOL_NS(sof_intel_board_set_bt_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
-int sof_intel_board_set_hdmi_in_link(struct device *dev,
- struct snd_soc_dai_link *link, int be_id,
- int ssp_hdmi)
+static int set_hdmi_in_link(struct device *dev, struct snd_soc_dai_link *link,
+ int be_id, int ssp_hdmi)
{
struct snd_soc_dai_link_component *cpus;
@@ -383,7 +378,6 @@ int sof_intel_board_set_hdmi_in_link(struct device *dev,
return 0;
}
-EXPORT_SYMBOL_NS(sof_intel_board_set_hdmi_in_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
static int calculate_num_links(struct sof_card_private *ctx)
{
@@ -427,6 +421,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
int ret;
int ssp_hdmi_in = 0;
unsigned long link_order, link;
+ unsigned long link_ids, be_id;
num_links = calculate_num_links(ctx);
@@ -440,22 +435,34 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
else
link_order = DEFAULT_LINK_ORDER;
- dev_dbg(dev, "create dai links, link_order 0x%lx\n", link_order);
+ if (ctx->link_id_overwrite)
+ link_ids = ctx->link_id_overwrite;
+ else
+ link_ids = 0;
+
+ dev_dbg(dev, "create dai links, link_order 0x%lx, id_overwrite 0x%lx\n",
+ link_order, link_ids);
while (link_order) {
link = link_order & SOF_LINK_ORDER_MASK;
link_order >>= SOF_LINK_ORDER_SHIFT;
+ if (ctx->link_id_overwrite) {
+ be_id = link_ids & SOF_LINK_IDS_MASK;
+ link_ids >>= SOF_LINK_IDS_SHIFT;
+ } else {
+ /* use array index as link id */
+ be_id = idx;
+ }
+
switch (link) {
case SOF_LINK_CODEC:
/* headphone codec */
if (ctx->codec_type == CODEC_NONE)
continue;
- ret = sof_intel_board_set_codec_link(dev, &links[idx],
- idx,
- ctx->codec_type,
- ctx->ssp_codec);
+ ret = set_ssp_codec_link(dev, &links[idx], be_id,
+ ctx->codec_type, ctx->ssp_codec);
if (ret) {
dev_err(dev, "fail to set codec link, ret %d\n",
ret);
@@ -471,8 +478,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
continue;
/* at least we have dmic01 */
- ret = sof_intel_board_set_dmic_link(dev, &links[idx],
- idx, SOF_DMIC_01);
+ ret = set_dmic_link(dev, &links[idx], be_id, SOF_DMIC_01);
if (ret) {
dev_err(dev, "fail to set dmic01 link, ret %d\n",
ret);
@@ -487,8 +493,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
continue;
/* set up 2 BE links at most */
- ret = sof_intel_board_set_dmic_link(dev, &links[idx],
- idx, SOF_DMIC_16K);
+ ret = set_dmic_link(dev, &links[idx], be_id,
+ SOF_DMIC_16K);
if (ret) {
dev_err(dev, "fail to set dmic16k link, ret %d\n",
ret);
@@ -500,10 +506,9 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
case SOF_LINK_IDISP_HDMI:
/* idisp HDMI */
for (i = 1; i <= ctx->hdmi_num; i++) {
- ret = sof_intel_board_set_intel_hdmi_link(dev,
- &links[idx],
- idx, i,
- ctx->hdmi.idisp_codec);
+ ret = set_idisp_hdmi_link(dev, &links[idx],
+ be_id, i,
+ ctx->hdmi.idisp_codec);
if (ret) {
dev_err(dev, "fail to set hdmi link, ret %d\n",
ret);
@@ -511,6 +516,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
}
idx++;
+ be_id++;
}
break;
case SOF_LINK_AMP:
@@ -518,10 +524,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
if (ctx->amp_type == CODEC_NONE)
continue;
- ret = sof_intel_board_set_ssp_amp_link(dev, &links[idx],
- idx,
- ctx->amp_type,
- ctx->ssp_amp);
+ ret = set_ssp_amp_link(dev, &links[idx], be_id,
+ ctx->amp_type, ctx->ssp_amp);
if (ret) {
dev_err(dev, "fail to set amp link, ret %d\n",
ret);
@@ -536,8 +540,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
if (!ctx->bt_offload_present)
continue;
- ret = sof_intel_board_set_bt_link(dev, &links[idx], idx,
- ctx->ssp_bt);
+ ret = set_bt_offload_link(dev, &links[idx], be_id,
+ ctx->ssp_bt);
if (ret) {
dev_err(dev, "fail to set bt link, ret %d\n",
ret);
@@ -549,10 +553,8 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
case SOF_LINK_HDMI_IN:
/* HDMI-In */
for_each_set_bit(ssp_hdmi_in, &ctx->ssp_mask_hdmi_in, 32) {
- ret = sof_intel_board_set_hdmi_in_link(dev,
- &links[idx],
- idx,
- ssp_hdmi_in);
+ ret = set_hdmi_in_link(dev, &links[idx], be_id,
+ ssp_hdmi_in);
if (ret) {
dev_err(dev, "fail to set hdmi-in link, ret %d\n",
ret);
@@ -560,6 +562,7 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
}
idx++;
+ be_id++;
}
break;
case SOF_LINK_NONE:
@@ -584,6 +587,49 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
}
EXPORT_SYMBOL_NS(sof_intel_board_set_dai_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
+struct sof_card_private *
+sof_intel_board_get_ctx(struct device *dev, unsigned long board_quirk)
+{
+ struct sof_card_private *ctx;
+
+ dev_dbg(dev, "create ctx, board_quirk 0x%lx\n", board_quirk);
+
+ ctx = devm_kzalloc(dev, sizeof(struct sof_card_private), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ctx->codec_type = sof_ssp_detect_codec_type(dev);
+ ctx->amp_type = sof_ssp_detect_amp_type(dev);
+
+ ctx->dmic_be_num = 2;
+ ctx->hdmi_num = (board_quirk & SOF_NUM_IDISP_HDMI_MASK) >>
+ SOF_NUM_IDISP_HDMI_SHIFT;
+ /* default number of HDMI DAI's */
+ if (!ctx->hdmi_num)
+ ctx->hdmi_num = 3;
+
+ /* port number/mask of peripherals attached to ssp interface */
+ if (ctx->codec_type != CODEC_NONE)
+ ctx->ssp_codec = (board_quirk & SOF_SSP_PORT_CODEC_MASK) >>
+ SOF_SSP_PORT_CODEC_SHIFT;
+
+ if (ctx->amp_type != CODEC_NONE)
+ ctx->ssp_amp = (board_quirk & SOF_SSP_PORT_AMP_MASK) >>
+ SOF_SSP_PORT_AMP_SHIFT;
+
+ if (board_quirk & SOF_BT_OFFLOAD_PRESENT) {
+ ctx->bt_offload_present = true;
+ ctx->ssp_bt = (board_quirk & SOF_SSP_PORT_BT_OFFLOAD_MASK) >>
+ SOF_SSP_PORT_BT_OFFLOAD_SHIFT;
+ }
+
+ ctx->ssp_mask_hdmi_in = (board_quirk & SOF_SSP_MASK_HDMI_CAPTURE_MASK) >>
+ SOF_SSP_MASK_HDMI_CAPTURE_SHIFT;
+
+ return ctx;
+}
+EXPORT_SYMBOL_NS(sof_intel_board_get_ctx, SND_SOC_INTEL_SOF_BOARD_HELPERS);
+
struct snd_soc_dai *get_codec_dai_by_name(struct snd_soc_pcm_runtime *rtd,
const char * const dai_name[], int num_dais)
{