@@ -90,8 +90,12 @@ struct asoc_sdw_mc_private {
bool ignore_internal_dmic;
void *private;
unsigned long mc_quirk;
+ int codec_info_list_count;
};
+extern struct asoc_sdw_codec_info codec_info_list[];
+int asoc_sdw_get_codec_info_list_count(void);
+
int asoc_sdw_startup(struct snd_pcm_substream *substream);
int asoc_sdw_prepare(struct snd_pcm_substream *substream);
int asoc_sdw_prepare(struct snd_pcm_substream *substream);
@@ -106,6 +110,15 @@ const char *asoc_sdw_get_codec_name(struct device *dev,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index);
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,
+ int *dai_index);
+
+int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);
+
/* DMIC support */
int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
@@ -548,50 +548,6 @@ static struct snd_soc_dai_link_component platform_component[] = {
}
};
-static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
- SND_SOC_DAPM_MIC("DMIC", NULL),
-};
-
-static const struct snd_soc_dapm_widget generic_jack_widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
-};
-
-static const struct snd_kcontrol_new generic_jack_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
-};
-
-static const struct snd_soc_dapm_widget generic_spk_widgets[] = {
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_kcontrol_new generic_spk_controls[] = {
- SOC_DAPM_PIN_SWITCH("Speaker"),
-};
-
-static const struct snd_soc_dapm_widget maxim_widgets[] = {
- SND_SOC_DAPM_SPK("Left Spk", NULL),
- SND_SOC_DAPM_SPK("Right Spk", NULL),
-};
-
-static const struct snd_kcontrol_new maxim_controls[] = {
- SOC_DAPM_PIN_SWITCH("Left Spk"),
- SOC_DAPM_PIN_SWITCH("Right Spk"),
-};
-
-static const struct snd_soc_dapm_widget rt700_widgets[] = {
- SND_SOC_DAPM_HP("Headphones", NULL),
- SND_SOC_DAPM_MIC("AMIC", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_kcontrol_new rt700_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphones"),
- SOC_DAPM_PIN_SWITCH("AMIC"),
- SOC_DAPM_PIN_SWITCH("Speaker"),
-};
-
static const struct snd_soc_ops sdw_ops = {
.startup = asoc_sdw_startup,
.prepare = asoc_sdw_prepare,
@@ -601,547 +557,6 @@ static const struct snd_soc_ops sdw_ops = {
.shutdown = asoc_sdw_shutdown,
};
-static struct asoc_sdw_codec_info codec_info_list[] = {
- {
- .part_id = 0x700,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt700-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .rtd_init = asoc_sdw_rt700_rtd_init,
- .controls = rt700_controls,
- .num_controls = ARRAY_SIZE(rt700_controls),
- .widgets = rt700_widgets,
- .num_widgets = ARRAY_SIZE(rt700_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x711,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt711-sdca-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .init = asoc_sdw_rt_sdca_jack_init,
- .exit = asoc_sdw_rt_sdca_jack_exit,
- .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x711,
- .version_id = 2,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt711-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .init = asoc_sdw_rt711_init,
- .exit = asoc_sdw_rt711_exit,
- .rtd_init = asoc_sdw_rt711_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x712,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt712-sdca-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .init = asoc_sdw_rt_sdca_jack_init,
- .exit = asoc_sdw_rt_sdca_jack_exit,
- .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {true, false},
- .dai_name = "rt712-sdca-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .init = asoc_sdw_rt_amp_init,
- .exit = asoc_sdw_rt_amp_exit,
- .rtd_init = asoc_sdw_rt712_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 2,
- },
- {
- .part_id = 0x1712,
- .version_id = 3,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt712-sdca-dmic-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x713,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt712-sdca-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .init = asoc_sdw_rt_sdca_jack_init,
- .exit = asoc_sdw_rt_sdca_jack_exit,
- .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1713,
- .version_id = 3,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt712-sdca-dmic-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1308,
- .acpi_id = "10EC1308",
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "rt1308-aif",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .init = asoc_sdw_rt_amp_init,
- .exit = asoc_sdw_rt_amp_exit,
- .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- .ops = &soc_sdw_rt1308_i2s_ops,
- },
- {
- .part_id = 0x1316,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt1316-aif",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
- .init = asoc_sdw_rt_amp_init,
- .exit = asoc_sdw_rt_amp_exit,
- .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1318,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt1318-aif",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
- .init = asoc_sdw_rt_amp_init,
- .exit = asoc_sdw_rt_amp_exit,
- .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x714,
- .version_id = 3,
- .ignore_internal_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-sdca-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x715,
- .version_id = 3,
- .ignore_internal_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-sdca-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x714,
- .version_id = 2,
- .ignore_internal_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x715,
- .version_id = 2,
- .ignore_internal_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x722,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt722-sdca-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .init = asoc_sdw_rt_sdca_jack_init,
- .exit = asoc_sdw_rt_sdca_jack_exit,
- .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {true, false},
- .dai_name = "rt722-sdca-aif2",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- /* No feedback capability is provided by rt722-sdca codec driver*/
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .init = asoc_sdw_rt_amp_init,
- .exit = asoc_sdw_rt_amp_exit,
- .rtd_init = asoc_sdw_rt722_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "rt722-sdca-aif3",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_rt_dmic_rtd_init,
- },
- },
- .dai_num = 3,
- },
- {
- .part_id = 0x8373,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "max98373-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
- .init = asoc_sdw_maxim_init,
- .rtd_init = asoc_sdw_maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x8363,
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "max98363-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .init = asoc_sdw_maxim_init,
- .rtd_init = asoc_sdw_maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x5682,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt5682-sdw",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .rtd_init = asoc_sdw_rt5682_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x3556,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "cs35l56-sdw1",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
- .init = asoc_sdw_cs_amp_init,
- .rtd_init = asoc_sdw_cs_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x4242,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "cs42l42-sdw",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- .rtd_init = asoc_sdw_cs42l42_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x4243,
- .codec_name = "cs42l43-codec",
- .count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
- .add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "cs42l43-dp5",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .rtd_init = asoc_sdw_cs42l43_hs_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "cs42l43-dp1",
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- .rtd_init = asoc_sdw_cs42l43_dmic_rtd_init,
- .widgets = generic_dmic_widgets,
- .num_widgets = ARRAY_SIZE(generic_dmic_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "cs42l43-dp2",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- },
- {
- .direction = {true, false},
- .dai_name = "cs42l43-dp6",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
- .init = asoc_sdw_cs42l43_spk_init,
- .rtd_init = asoc_sdw_cs42l43_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- .quirk = SOC_SDW_CODEC_SPKR | SOC_SDW_SIDECAR_AMPS,
- },
- },
- .dai_num = 4,
- },
- {
- .part_id = 0xaaaa, /* generic codec mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0xaa55, /* headset codec mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_JACK,
- .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x55aa, /* amplifier mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOC_SDW_DAI_TYPE_AMP,
- .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x5555,
- .version_id = 0,
- .dais = {
- {
- .dai_name = "sdw-mockup-aif1",
- .direction = {false, true},
- .dai_type = SOC_SDW_DAI_TYPE_MIC,
- .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
- },
- },
- .dai_num = 1,
- },
-};
-
-static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr)
-{
- unsigned int part_id, sdw_version;
- int i;
-
- part_id = SDW_PART_ID(adr);
- sdw_version = SDW_VERSION(adr);
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
- /*
- * A codec info is for all sdw version with the part id if
- * version_id is not specified in the codec info.
- */
- if (part_id == codec_info_list[i].part_id &&
- (!codec_info_list[i].version_id ||
- sdw_version == codec_info_list[i].version_id))
- return &codec_info_list[i];
-
- return NULL;
-
-}
-
-static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id)
-{
- int i;
-
- if (!acpi_id[0])
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
- if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
- return &codec_info_list[i];
-
- return NULL;
-}
-
-static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,
- int *dai_index)
-{
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
- for (j = 0; j < codec_info_list[i].dai_num; j++) {
- if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
- *dai_index = j;
- return &codec_info_list[i];
- }
- }
- }
-
- return NULL;
-}
-
static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
int *be_id, char *name, int playback, int capture,
struct snd_soc_dai_link_component *cpus, int cpus_num,
@@ -1190,69 +605,6 @@ static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai
return 0;
}
-static int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_card *card = rtd->card;
- struct asoc_sdw_codec_info *codec_info;
- struct snd_soc_dai *dai;
- int dai_index;
- int ret;
- int i;
-
- for_each_rtd_codec_dais(rtd, i, dai) {
- codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index);
- if (!codec_info)
- return -EINVAL;
-
- /*
- * A codec dai can be connected to different dai links for capture and playback,
- * but we only need to call the rtd_init function once.
- * The rtd_init for each codec dai is independent. So, the order of rtd_init
- * doesn't matter.
- */
- if (codec_info->dais[dai_index].rtd_init_done)
- continue;
-
- /*
- * Add card controls and dapm widgets for the first codec dai.
- * The controls and widgets will be used for all codec dais.
- */
-
- if (i > 0)
- goto skip_add_controls_widgets;
-
- if (codec_info->dais[dai_index].controls) {
- ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls,
- codec_info->dais[dai_index].num_controls);
- if (ret) {
- dev_err(card->dev, "%#x controls addition failed: %d\n",
- codec_info->part_id, ret);
- return ret;
- }
- }
- if (codec_info->dais[dai_index].widgets) {
- ret = snd_soc_dapm_new_controls(&card->dapm,
- codec_info->dais[dai_index].widgets,
- codec_info->dais[dai_index].num_widgets);
- if (ret) {
- dev_err(card->dev, "%#x widgets addition failed: %d\n",
- codec_info->part_id, ret);
- return ret;
- }
- }
-
-skip_add_controls_widgets:
- if (codec_info->dais[dai_index].rtd_init) {
- ret = codec_info->dais[dai_index].rtd_init(rtd, dai);
- if (ret)
- return ret;
- }
- codec_info->dais[dai_index].rtd_init_done = true;
- }
-
- return 0;
-}
-
struct sof_sdw_endpoint {
struct list_head list;
@@ -1871,7 +1223,7 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
int ret = 0;
int i;
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ for (i = 0; i < ctx->codec_info_list_count; i++) {
if (codec_info_list[i].codec_card_late_probe) {
ret = codec_info_list[i].codec_card_late_probe(card);
@@ -1907,10 +1259,11 @@ static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card
static void mc_dailink_exit_loop(struct snd_soc_card *card)
{
struct snd_soc_dai_link *dai_link;
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret;
int i, j;
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ for (i = 0; i < ctx->codec_info_list_count; i++) {
for (j = 0; j < codec_info_list[i].dai_num; j++) {
codec_info_list[i].dais[j].rtd_init_done = false;
/* Check each dai in codec_info_lis to see if it is used in the link */
@@ -1955,6 +1308,7 @@ static int mc_probe(struct platform_device *pdev)
return -ENOMEM;
ctx->private = intel_ctx;
+ ctx->codec_info_list_count = asoc_sdw_get_codec_info_list_count();
card = &ctx->card;
card->dev = &pdev->dev;
card->name = "soundwire";
@@ -1975,7 +1329,7 @@ static int mc_probe(struct platform_device *pdev)
ctx->mc_quirk = sof_sdw_quirk;
/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ for (i = 0; i < ctx->codec_info_list_count; i++)
codec_info_list[i].amp_num = 0;
if (mach->mach_params.subsystem_id_set) {
@@ -1993,7 +1347,7 @@ static int mc_probe(struct platform_device *pdev)
* amp_num will only be increased for active amp
* codecs on used platform
*/
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ for (i = 0; i < ctx->codec_info_list_count; i++)
amp_num += codec_info_list[i].amp_num;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
@@ -12,6 +12,663 @@
#include <linux/soundwire/sdw_type.h>
#include <sound/soc_sdw_utils.h>
+static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
+ SND_SOC_DAPM_MIC("DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_widget generic_jack_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_kcontrol_new generic_jack_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget generic_spk_widgets[] = {
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_kcontrol_new generic_spk_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+static const struct snd_soc_dapm_widget maxim_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_kcontrol_new maxim_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget rt700_widgets[] = {
+ SND_SOC_DAPM_HP("Headphones", NULL),
+ SND_SOC_DAPM_MIC("AMIC", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_kcontrol_new rt700_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphones"),
+ SOC_DAPM_PIN_SWITCH("AMIC"),
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+struct asoc_sdw_codec_info codec_info_list[] = {
+ {
+ .part_id = 0x700,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt700-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_rt700_rtd_init,
+ .controls = rt700_controls,
+ .num_controls = ARRAY_SIZE(rt700_controls),
+ .widgets = rt700_widgets,
+ .num_widgets = ARRAY_SIZE(rt700_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x711,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt711-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x711,
+ .version_id = 2,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt711-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt711_init,
+ .exit = asoc_sdw_rt711_exit,
+ .rtd_init = asoc_sdw_rt711_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x712,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt712-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "rt712-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt712_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 2,
+ },
+ {
+ .part_id = 0x1712,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt712-sdca-dmic-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x713,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt712-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1713,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt712-sdca-dmic-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1308,
+ .acpi_id = "10EC1308",
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "rt1308-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ .ops = &soc_sdw_rt1308_i2s_ops,
+ },
+ {
+ .part_id = 0x1316,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt1316-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1318,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt1318-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x714,
+ .version_id = 3,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x715,
+ .version_id = 3,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x714,
+ .version_id = 2,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x715,
+ .version_id = 2,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x722,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt722-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "rt722-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ /* No feedback capability is provided by rt722-sdca codec driver*/
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt722_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "rt722-sdca-aif3",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 3,
+ },
+ {
+ .part_id = 0x8373,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "max98373-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_maxim_init,
+ .rtd_init = asoc_sdw_maxim_spk_rtd_init,
+ .controls = maxim_controls,
+ .num_controls = ARRAY_SIZE(maxim_controls),
+ .widgets = maxim_widgets,
+ .num_widgets = ARRAY_SIZE(maxim_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x8363,
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "max98363-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_maxim_init,
+ .rtd_init = asoc_sdw_maxim_spk_rtd_init,
+ .controls = maxim_controls,
+ .num_controls = ARRAY_SIZE(maxim_controls),
+ .widgets = maxim_widgets,
+ .num_widgets = ARRAY_SIZE(maxim_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x5682,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt5682-sdw",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_rt5682_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x3556,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "cs35l56-sdw1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_cs_amp_init,
+ .rtd_init = asoc_sdw_cs_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x4242,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "cs42l42-sdw",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l42_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x4243,
+ .codec_name = "cs42l43-codec",
+ .count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
+ .add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "cs42l43-dp5",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_hs_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_dmic_rtd_init,
+ .widgets = generic_dmic_widgets,
+ .num_widgets = ARRAY_SIZE(generic_dmic_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp2",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "cs42l43-dp6",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_cs42l43_spk_init,
+ .rtd_init = asoc_sdw_cs42l43_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ .quirk = SOC_SDW_CODEC_SPKR | SOC_SDW_SIDECAR_AMPS,
+ },
+ },
+ .dai_num = 4,
+ },
+ {
+ .part_id = 0xaaaa, /* generic codec mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0xaa55, /* headset codec mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x55aa, /* amplifier mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x5555,
+ .version_id = 0,
+ .dais = {
+ {
+ .dai_name = "sdw-mockup-aif1",
+ .direction = {false, true},
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+};
+EXPORT_SYMBOL_NS(codec_info_list, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_get_codec_info_list_count(void)
+{
+ return ARRAY_SIZE(codec_info_list);
+};
+EXPORT_SYMBOL_NS(asoc_sdw_get_codec_info_list_count, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr)
+{
+ unsigned int part_id, sdw_version;
+ int i;
+
+ part_id = SDW_PART_ID(adr);
+ sdw_version = SDW_VERSION(adr);
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ /*
+ * A codec info is for all sdw version with the part id if
+ * version_id is not specified in the codec info.
+ */
+ if (part_id == codec_info_list[i].part_id &&
+ (!codec_info_list[i].version_id ||
+ sdw_version == codec_info_list[i].version_id))
+ return &codec_info_list[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id)
+{
+ int i;
+
+ if (!acpi_id[0])
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
+ return &codec_info_list[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_acpi, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, int *dai_index)
+{
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ for (j = 0; j < codec_info_list[i].dai_num; j++) {
+ if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
+ *dai_index = j;
+ return &codec_info_list[i];
+ }
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct asoc_sdw_codec_info *codec_info;
+ struct snd_soc_dai *dai;
+ int dai_index;
+ int ret;
+ int i;
+
+ for_each_rtd_codec_dais(rtd, i, dai) {
+ codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index);
+ if (!codec_info)
+ return -EINVAL;
+
+ /*
+ * A codec dai can be connected to different dai links for capture and playback,
+ * but we only need to call the rtd_init function once.
+ * The rtd_init for each codec dai is independent. So, the order of rtd_init
+ * doesn't matter.
+ */
+ if (codec_info->dais[dai_index].rtd_init_done)
+ continue;
+
+ /*
+ * Add card controls and dapm widgets for the first codec dai.
+ * The controls and widgets will be used for all codec dais.
+ */
+
+ if (i > 0)
+ goto skip_add_controls_widgets;
+
+ if (codec_info->dais[dai_index].controls) {
+ ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls,
+ codec_info->dais[dai_index].num_controls);
+ if (ret) {
+ dev_err(card->dev, "%#x controls addition failed: %d\n",
+ codec_info->part_id, ret);
+ return ret;
+ }
+ }
+ if (codec_info->dais[dai_index].widgets) {
+ ret = snd_soc_dapm_new_controls(&card->dapm,
+ codec_info->dais[dai_index].widgets,
+ codec_info->dais[dai_index].num_widgets);
+ if (ret) {
+ dev_err(card->dev, "%#x widgets addition failed: %d\n",
+ codec_info->part_id, ret);
+ return ret;
+ }
+ }
+
+skip_add_controls_widgets:
+ if (codec_info->dais[dai_index].rtd_init) {
+ ret = codec_info->dais[dai_index].rtd_init(rtd, dai);
+ if (ret)
+ return ret;
+ }
+ codec_info->dais[dai_index].rtd_init_done = true;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_rtd_init, SND_SOC_SDW_UTILS);
+
/* these wrappers are only needed to avoid typecast compilation errors */
int asoc_sdw_startup(struct snd_pcm_substream *substream)
{