summaryrefslogtreecommitdiffstats
path: root/sound/soc/mediatek/common/mtk-afe-platform-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/mediatek/common/mtk-afe-platform-driver.c')
-rw-r--r--sound/soc/mediatek/common/mtk-afe-platform-driver.c103
1 files changed, 89 insertions, 14 deletions
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
index 53215b52e4f24..51ec4ff6ed955 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* mtk-afe-platform-driver.c -- Mediatek afe platform driver
*
* Copyright (c) 2016 MediaTek Inc.
* Author: Garlic Tseng <garlic.tseng@mediatek.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/module.h>
@@ -21,6 +13,86 @@
#include "mtk-afe-platform-driver.h"
#include "mtk-base-afe.h"
+int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)
+{
+ struct snd_soc_dai_driver *sub_dai_drivers;
+ size_t num_dai_drivers = 0, dai_idx = 0;
+ int i;
+
+ if (!afe->sub_dais) {
+ dev_err(afe->dev, "%s(), sub_dais == NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ /* calcualte total dai driver size */
+ for (i = 0; i < afe->num_sub_dais; i++) {
+ if (afe->sub_dais[i].dai_drivers &&
+ afe->sub_dais[i].num_dai_drivers != 0)
+ num_dai_drivers += afe->sub_dais[i].num_dai_drivers;
+ }
+
+ dev_info(afe->dev, "%s(), num of dai %zd\n", __func__, num_dai_drivers);
+
+ /* combine sub_dais */
+ afe->num_dai_drivers = num_dai_drivers;
+ afe->dai_drivers = devm_kcalloc(afe->dev,
+ num_dai_drivers,
+ sizeof(struct snd_soc_dai_driver),
+ GFP_KERNEL);
+ if (!afe->dai_drivers)
+ return -ENOMEM;
+
+ for (i = 0; i < afe->num_sub_dais; i++) {
+ if (afe->sub_dais[i].dai_drivers &&
+ afe->sub_dais[i].num_dai_drivers != 0) {
+ sub_dai_drivers = afe->sub_dais[i].dai_drivers;
+ /* dai driver */
+ memcpy(&afe->dai_drivers[dai_idx],
+ sub_dai_drivers,
+ afe->sub_dais[i].num_dai_drivers *
+ sizeof(struct snd_soc_dai_driver));
+ dai_idx += afe->sub_dais[i].num_dai_drivers;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai);
+
+int mtk_afe_add_sub_dai_control(struct snd_soc_component *component)
+{
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ int i;
+
+ if (!afe->sub_dais) {
+ dev_err(afe->dev, "%s(), sub_dais == NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < afe->num_sub_dais; i++) {
+ if (afe->sub_dais[i].controls)
+ snd_soc_add_component_controls(component,
+ afe->sub_dais[i].controls,
+ afe->sub_dais[i].num_controls);
+
+ if (afe->sub_dais[i].dapm_widgets)
+ snd_soc_dapm_new_controls(&component->dapm,
+ afe->sub_dais[i].dapm_widgets,
+ afe->sub_dais[i].num_dapm_widgets);
+
+ if (afe->sub_dais[i].dapm_routes)
+ snd_soc_dapm_add_routes(&component->dapm,
+ afe->sub_dais[i].dapm_routes,
+ afe->sub_dais[i].num_dapm_routes);
+ }
+
+ snd_soc_dapm_new_widgets(component->dapm.card);
+
+ return 0;
+
+}
+EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control);
+
static snd_pcm_uframes_t mtk_afe_pcm_pointer
(struct snd_pcm_substream *substream)
{
@@ -56,28 +128,31 @@ POINTER_RETURN_FRAMES:
return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
}
-static const struct snd_pcm_ops mtk_afe_pcm_ops = {
+const struct snd_pcm_ops mtk_afe_pcm_ops = {
.ioctl = snd_pcm_lib_ioctl,
.pointer = mtk_afe_pcm_pointer,
};
+EXPORT_SYMBOL_GPL(mtk_afe_pcm_ops);
-static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
+int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
size_t size;
- struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
size = afe->mtk_afe_hardware->buffer_bytes_max;
return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- card->dev, size, size);
+ afe->dev,
+ size, size);
}
+EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);
-static void mtk_afe_pcm_free(struct snd_pcm *pcm)
+void mtk_afe_pcm_free(struct snd_pcm *pcm)
{
snd_pcm_lib_preallocate_free_for_all(pcm);
}
+EXPORT_SYMBOL_GPL(mtk_afe_pcm_free);
const struct snd_soc_component_driver mtk_afe_pcm_platform = {
.name = AFE_PCM_NAME,