@@ -139,6 +139,57 @@ void clean_card_reference(struct snd_soc_card *card)
}
EXPORT_SYMBOL_GPL(clean_card_reference);
+int mtk_soundcard_startup(struct snd_pcm_substream *substream,
+ enum mtk_pcm_constraint_type ctype)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct mtk_soc_card_data *soc_card = snd_soc_card_get_drvdata(rtd->card);
+ const struct mtk_pcm_constraints_data *mpc = &soc_card->card_data->pcm_constraints[ctype];
+ int ret;
+
+ if (unlikely(!mpc))
+ return -EINVAL;
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &mpc->rates);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &mpc->channels);
+ if (ret < 0) {
+ dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_soundcard_startup);
+
+static int mtk_soundcard_playback_startup(struct snd_pcm_substream *substream)
+{
+ return mtk_soundcard_startup(substream, MTK_CONSTRAINT_PLAYBACK);
+}
+
+const struct snd_soc_ops mtk_soundcard_common_playback_ops = {
+ .startup = mtk_soundcard_playback_startup,
+};
+EXPORT_SYMBOL_GPL(mtk_soundcard_common_playback_ops);
+
+static int mtk_soundcard_capture_startup(struct snd_pcm_substream *substream)
+{
+ return mtk_soundcard_startup(substream, MTK_CONSTRAINT_CAPTURE);
+}
+
+const struct snd_soc_ops mtk_soundcard_common_capture_ops = {
+ .startup = mtk_soundcard_capture_startup,
+};
+EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops);
+
int mtk_soundcard_common_probe(struct platform_device *pdev)
{
struct device_node *platform_node, *adsp_node;
@@ -11,11 +11,26 @@
struct mtk_sof_priv;
struct mtk_soc_card_data;
+struct snd_pcm_hw_constraint_list;
+
+enum mtk_pcm_constraint_type {
+ MTK_CONSTRAINT_PLAYBACK,
+ MTK_CONSTRAINT_CAPTURE,
+ MTK_CONSTRAINT_HDMIDP,
+ MTK_CONSTRAINT_MAX
+};
+
+struct mtk_pcm_constraints_data {
+ const struct snd_pcm_hw_constraint_list channels;
+ const struct snd_pcm_hw_constraint_list rates;
+};
struct mtk_platform_card_data {
struct snd_soc_card *card;
struct snd_soc_jack *jacks;
+ const struct mtk_pcm_constraints_data *pcm_constraints;
u8 num_jacks;
+ u8 num_pcm_constraints;
u8 flags;
};
@@ -23,9 +38,18 @@ struct mtk_soundcard_pdata {
const char *card_name;
struct mtk_platform_card_data *card_data;
const struct mtk_sof_priv *sof_priv;
+
int (*soc_probe)(struct mtk_soc_card_data *card_data, bool legacy);
};
+/* Common playback/capture card startup ops */
+extern const struct snd_soc_ops mtk_soundcard_common_playback_ops;
+extern const struct snd_soc_ops mtk_soundcard_common_capture_ops;
+
+/* Exported for custom/extended soundcard startup ops */
+int mtk_soundcard_startup(struct snd_pcm_substream *substream,
+ enum mtk_pcm_constraint_type ctype);
+
int parse_dai_link_info(struct snd_soc_card *card);
void clean_card_reference(struct snd_soc_card *card);
int mtk_soundcard_common_probe(struct platform_device *pdev);
MediaTek platforms are typically setting PCM rate and channels constraints for playback, capture and HDMI/DisplayPort playback: commonize the startup callback by adding the PCM constraints data to the mtk_platform_card_data structure and by reusing the common mtk_soundcard_startup() function for all of them by getting back the parameters from the aforementioned struct. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- .../mediatek/common/mtk-soundcard-driver.c | 51 +++++++++++++++++++ .../mediatek/common/mtk-soundcard-driver.h | 24 +++++++++ 2 files changed, 75 insertions(+)