From nobody Sun Sep 22 09:29:07 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 744A1C4332F for ; Sun, 13 Mar 2022 15:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234803AbiCMPMB (ORCPT ); Sun, 13 Mar 2022 11:12:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234752AbiCMPLu (ORCPT ); Sun, 13 Mar 2022 11:11:50 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82C4185BC7; Sun, 13 Mar 2022 08:10:41 -0700 (PDT) X-UUID: 6197ce55dbf04168a48f5cbb02327327-20220313 X-UUID: 6197ce55dbf04168a48f5cbb02327327-20220313 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 498316143; Sun, 13 Mar 2022 23:10:32 +0800 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs10n1.mediatek.inc (172.21.101.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.792.15; Sun, 13 Mar 2022 23:10:30 +0800 Received: from localhost.localdomain (10.17.3.154) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sun, 13 Mar 2022 23:10:29 +0800 From: Jiaxin Yu To: , , CC: , , , , , , , , , , , Jiaxin Yu Subject: [v3 05/19] ASoC: mediatek: mt8186: support hostless in platform driver Date: Sun, 13 Mar 2022 23:10:09 +0800 Message-ID: <20220313151023.21229-6-jiaxin.yu@mediatek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220313151023.21229-1-jiaxin.yu@mediatek.com> References: <20220313151023.21229-1-jiaxin.yu@mediatek.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add mt8186 hostless dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno --- .../soc/mediatek/mt8186/mt8186-dai-hostless.c | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hostless.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c b/sound/soc/me= diatek/mt8186/mt8186-dai-hostless.c new file mode 100644 index 000000000000..bf0d83840cf4 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI Hostless Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include "mt8186-afe-common.h" + +static const struct snd_pcm_hardware mt8186_hostless_hardware =3D { + .info =3D (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .period_bytes_min =3D 256, + .period_bytes_max =3D 4 * 48 * 1024, + .periods_min =3D 2, + .periods_max =3D 256, + .buffer_bytes_max =3D 4 * 48 * 1024, + .fifo_size =3D 0, +}; + +/* dai component */ +static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] =3D { + /* Hostless ADDA Loopback */ + {"ADDA_DL_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S1_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S1_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S3_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S3_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S3_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S3_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"Hostless LPBK UL", NULL, "ADDA_UL_Mux"}, + + /* Hostelss FM */ + /* connsys_i2s to hw gain 1*/ + {"Hostless FM UL", NULL, "Connsys I2S"}, + + {"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1 Switch", "Hostless FM DL"}, + {"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2 Switch", "Hostless FM DL"}, + /* hw gain to adda dl */ + {"Hostless FM UL", NULL, "HW Gain 1 Out"}, + + {"ADDA_DL_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"ADDA_DL_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + /* hw gain to i2s3 */ + {"I2S3_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"I2S3_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + /* hw gain to i2s1 */ + {"I2S1_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"I2S1_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + + /* Hostless_SRC */ + {"ADDA_DL_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"ADDA_DL_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"I2S1_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"I2S1_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"I2S3_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"I2S3_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"Hostless_SRC_1_UL", NULL, "HW_SRC_1_Out"}, + + /* Hostless_SRC_bargein */ + {"HW_SRC_1_IN_CH1", "I2S0_CH1 Switch", "Hostless_SRC_Bargein_DL"}, + {"HW_SRC_1_IN_CH2", "I2S0_CH2 Switch", "Hostless_SRC_Bargein_DL"}, + {"Hostless_SRC_Bargein_UL", NULL, "I2S0"}, + + /* Hostless AAudio */ + {"Hostless HW Gain AAudio In", NULL, "HW Gain 2 In"}, + {"Hostless SRC AAudio UL", NULL, "HW Gain 2 Out"}, + {"HW_SRC_2_IN_CH1", "HW_GAIN2_OUT_CH1 Switch", "Hostless SRC AAudio DL"}, + {"HW_SRC_2_IN_CH2", "HW_GAIN2_OUT_CH2 Switch", "Hostless SRC AAudio DL"}, +}; + +/* dai ops */ +static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime =3D substream->runtime; + int ret; + + snd_soc_set_runtime_hwparams(substream, &mt8186_hostless_hardware); + + ret =3D snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_hostless_ops =3D { + .startup =3D mtk_dai_hostless_startup, +}; + +/* dai driver */ +#define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_hostless_driver[] =3D { + { + .name =3D "Hostless LPBK DAI", + .id =3D MT8186_DAI_HOSTLESS_LPBK, + .playback =3D { + .stream_name =3D "Hostless LPBK DL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .capture =3D { + .stream_name =3D "Hostless LPBK UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless FM DAI", + .id =3D MT8186_DAI_HOSTLESS_FM, + .playback =3D { + .stream_name =3D "Hostless FM DL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .capture =3D { + .stream_name =3D "Hostless FM UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_SRC_1_DAI", + .id =3D MT8186_DAI_HOSTLESS_SRC_1, + .playback =3D { + .stream_name =3D "Hostless_SRC_1_DL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .capture =3D { + .stream_name =3D "Hostless_SRC_1_UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_SRC_Bargein_DAI", + .id =3D MT8186_DAI_HOSTLESS_SRC_BARGEIN, + .playback =3D { + .stream_name =3D "Hostless_SRC_Bargein_DL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .capture =3D { + .stream_name =3D "Hostless_SRC_Bargein_UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + /* BE dai */ + { + .name =3D "Hostless_UL1 DAI", + .id =3D MT8186_DAI_HOSTLESS_UL1, + .capture =3D { + .stream_name =3D "Hostless_UL1 UL", + .channels_min =3D 1, + .channels_max =3D 4, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_UL2 DAI", + .id =3D MT8186_DAI_HOSTLESS_UL2, + .capture =3D { + .stream_name =3D "Hostless_UL2 UL", + .channels_min =3D 1, + .channels_max =3D 4, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_UL3 DAI", + .id =3D MT8186_DAI_HOSTLESS_UL3, + .capture =3D { + .stream_name =3D "Hostless_UL3 UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_UL5 DAI", + .id =3D MT8186_DAI_HOSTLESS_UL5, + .capture =3D { + .stream_name =3D "Hostless_UL5 UL", + .channels_min =3D 1, + .channels_max =3D 12, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless_UL6 DAI", + .id =3D MT8186_DAI_HOSTLESS_UL6, + .capture =3D { + .stream_name =3D "Hostless_UL6 UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless HW Gain AAudio DAI", + .id =3D MT8186_DAI_HOSTLESS_HW_GAIN_AAUDIO, + .capture =3D { + .stream_name =3D "Hostless HW Gain AAudio In", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, + { + .name =3D "Hostless SRC AAudio DAI", + .id =3D MT8186_DAI_HOSTLESS_SRC_AAUDIO, + .playback =3D { + .stream_name =3D "Hostless SRC AAudio DL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .capture =3D { + .stream_name =3D "Hostless SRC AAudio UL", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D MTK_HOSTLESS_RATES, + .formats =3D MTK_HOSTLESS_FORMATS, + }, + .ops =3D &mtk_dai_hostless_ops, + }, +}; + +int mt8186_dai_hostless_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai =3D devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers =3D mtk_dai_hostless_driver; + dai->num_dai_drivers =3D ARRAY_SIZE(mtk_dai_hostless_driver); + + dai->dapm_routes =3D mtk_dai_hostless_routes; + dai->num_dapm_routes =3D ARRAY_SIZE(mtk_dai_hostless_routes); + + return 0; +} --=20 2.18.0