Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // MediaTek ALSA SoC Audio DAI Hostless Control
0004 //
0005 // Copyright (c) 2022 MediaTek Inc.
0006 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
0007 
0008 #include "mt8186-afe-common.h"
0009 
0010 static const struct snd_pcm_hardware mt8186_hostless_hardware = {
0011     .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
0012          SNDRV_PCM_INFO_MMAP_VALID),
0013     .period_bytes_min = 256,
0014     .period_bytes_max = 4 * 48 * 1024,
0015     .periods_min = 2,
0016     .periods_max = 256,
0017     .buffer_bytes_max = 4 * 48 * 1024,
0018     .fifo_size = 0,
0019 };
0020 
0021 /* dai component */
0022 static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = {
0023     /* Hostless ADDA Loopback */
0024     {"ADDA_DL_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
0025     {"ADDA_DL_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
0026     {"ADDA_DL_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
0027     {"ADDA_DL_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
0028     {"I2S1_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
0029     {"I2S1_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
0030     {"I2S3_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
0031     {"I2S3_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
0032     {"I2S3_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
0033     {"I2S3_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
0034     {"Hostless LPBK UL", NULL, "ADDA_UL_Mux"},
0035 
0036     /* Hostelss FM */
0037     /* connsys_i2s to hw gain 1*/
0038     {"Hostless FM UL", NULL, "Connsys I2S"},
0039 
0040     {"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1 Switch", "Hostless FM DL"},
0041     {"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2 Switch", "Hostless FM DL"},
0042     /* hw gain to adda dl */
0043     {"Hostless FM UL", NULL, "HW Gain 1 Out"},
0044 
0045     {"ADDA_DL_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
0046     {"ADDA_DL_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
0047     /* hw gain to i2s3 */
0048     {"I2S3_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
0049     {"I2S3_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
0050     /* hw gain to i2s1 */
0051     {"I2S1_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
0052     {"I2S1_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
0053 
0054     /* Hostless_SRC */
0055     {"ADDA_DL_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
0056     {"ADDA_DL_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
0057     {"I2S1_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
0058     {"I2S1_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
0059     {"I2S3_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
0060     {"I2S3_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
0061     {"Hostless_SRC_1_UL", NULL, "HW_SRC_1_Out"},
0062 
0063     /* Hostless_SRC_bargein */
0064     {"HW_SRC_1_IN_CH1", "I2S0_CH1 Switch", "Hostless_SRC_Bargein_DL"},
0065     {"HW_SRC_1_IN_CH2", "I2S0_CH2 Switch", "Hostless_SRC_Bargein_DL"},
0066     {"Hostless_SRC_Bargein_UL", NULL, "I2S0"},
0067 
0068     /* Hostless AAudio */
0069     {"Hostless HW Gain AAudio In", NULL, "HW Gain 2 In"},
0070     {"Hostless SRC AAudio UL", NULL, "HW Gain 2 Out"},
0071     {"HW_SRC_2_IN_CH1", "HW_GAIN2_OUT_CH1 Switch", "Hostless SRC AAudio DL"},
0072     {"HW_SRC_2_IN_CH2", "HW_GAIN2_OUT_CH2 Switch", "Hostless SRC AAudio DL"},
0073 };
0074 
0075 /* dai ops */
0076 static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,
0077                     struct snd_soc_dai *dai)
0078 {
0079     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0080     struct snd_pcm_runtime *runtime = substream->runtime;
0081     int ret;
0082 
0083     snd_soc_set_runtime_hwparams(substream, &mt8186_hostless_hardware);
0084 
0085     ret = snd_pcm_hw_constraint_integer(runtime,
0086                         SNDRV_PCM_HW_PARAM_PERIODS);
0087     if (ret < 0) {
0088         dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
0089         return ret;
0090     }
0091 
0092     return 0;
0093 }
0094 
0095 static const struct snd_soc_dai_ops mtk_dai_hostless_ops = {
0096     .startup = mtk_dai_hostless_startup,
0097 };
0098 
0099 /* dai driver */
0100 #define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\
0101                SNDRV_PCM_RATE_88200 |\
0102                SNDRV_PCM_RATE_96000 |\
0103                SNDRV_PCM_RATE_176400 |\
0104                SNDRV_PCM_RATE_192000)
0105 
0106 #define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
0107                  SNDRV_PCM_FMTBIT_S24_LE |\
0108                  SNDRV_PCM_FMTBIT_S32_LE)
0109 
0110 static struct snd_soc_dai_driver mtk_dai_hostless_driver[] = {
0111     {
0112         .name = "Hostless LPBK DAI",
0113         .id = MT8186_DAI_HOSTLESS_LPBK,
0114         .playback = {
0115             .stream_name = "Hostless LPBK DL",
0116             .channels_min = 1,
0117             .channels_max = 2,
0118             .rates = MTK_HOSTLESS_RATES,
0119             .formats = MTK_HOSTLESS_FORMATS,
0120         },
0121         .capture = {
0122             .stream_name = "Hostless LPBK UL",
0123             .channels_min = 1,
0124             .channels_max = 2,
0125             .rates = MTK_HOSTLESS_RATES,
0126             .formats = MTK_HOSTLESS_FORMATS,
0127         },
0128         .ops = &mtk_dai_hostless_ops,
0129     },
0130     {
0131         .name = "Hostless FM DAI",
0132         .id = MT8186_DAI_HOSTLESS_FM,
0133         .playback = {
0134             .stream_name = "Hostless FM DL",
0135             .channels_min = 1,
0136             .channels_max = 2,
0137             .rates = MTK_HOSTLESS_RATES,
0138             .formats = MTK_HOSTLESS_FORMATS,
0139         },
0140         .capture = {
0141             .stream_name = "Hostless FM UL",
0142             .channels_min = 1,
0143             .channels_max = 2,
0144             .rates = MTK_HOSTLESS_RATES,
0145             .formats = MTK_HOSTLESS_FORMATS,
0146         },
0147         .ops = &mtk_dai_hostless_ops,
0148     },
0149     {
0150         .name = "Hostless_SRC_1_DAI",
0151         .id = MT8186_DAI_HOSTLESS_SRC_1,
0152         .playback = {
0153             .stream_name = "Hostless_SRC_1_DL",
0154             .channels_min = 1,
0155             .channels_max = 2,
0156             .rates = MTK_HOSTLESS_RATES,
0157             .formats = MTK_HOSTLESS_FORMATS,
0158         },
0159         .capture = {
0160             .stream_name = "Hostless_SRC_1_UL",
0161             .channels_min = 1,
0162             .channels_max = 2,
0163             .rates = MTK_HOSTLESS_RATES,
0164             .formats = MTK_HOSTLESS_FORMATS,
0165         },
0166         .ops = &mtk_dai_hostless_ops,
0167     },
0168     {
0169         .name = "Hostless_SRC_Bargein_DAI",
0170         .id = MT8186_DAI_HOSTLESS_SRC_BARGEIN,
0171         .playback = {
0172             .stream_name = "Hostless_SRC_Bargein_DL",
0173             .channels_min = 1,
0174             .channels_max = 2,
0175             .rates = MTK_HOSTLESS_RATES,
0176             .formats = MTK_HOSTLESS_FORMATS,
0177         },
0178         .capture = {
0179             .stream_name = "Hostless_SRC_Bargein_UL",
0180             .channels_min = 1,
0181             .channels_max = 2,
0182             .rates = MTK_HOSTLESS_RATES,
0183             .formats = MTK_HOSTLESS_FORMATS,
0184         },
0185         .ops = &mtk_dai_hostless_ops,
0186     },
0187     /* BE dai */
0188     {
0189         .name = "Hostless_UL1 DAI",
0190         .id = MT8186_DAI_HOSTLESS_UL1,
0191         .capture = {
0192             .stream_name = "Hostless_UL1 UL",
0193             .channels_min = 1,
0194             .channels_max = 4,
0195             .rates = MTK_HOSTLESS_RATES,
0196             .formats = MTK_HOSTLESS_FORMATS,
0197         },
0198         .ops = &mtk_dai_hostless_ops,
0199     },
0200     {
0201         .name = "Hostless_UL2 DAI",
0202         .id = MT8186_DAI_HOSTLESS_UL2,
0203         .capture = {
0204             .stream_name = "Hostless_UL2 UL",
0205             .channels_min = 1,
0206             .channels_max = 4,
0207             .rates = MTK_HOSTLESS_RATES,
0208             .formats = MTK_HOSTLESS_FORMATS,
0209         },
0210         .ops = &mtk_dai_hostless_ops,
0211     },
0212     {
0213         .name = "Hostless_UL3 DAI",
0214         .id = MT8186_DAI_HOSTLESS_UL3,
0215         .capture = {
0216             .stream_name = "Hostless_UL3 UL",
0217             .channels_min = 1,
0218             .channels_max = 2,
0219             .rates = MTK_HOSTLESS_RATES,
0220             .formats = MTK_HOSTLESS_FORMATS,
0221         },
0222         .ops = &mtk_dai_hostless_ops,
0223     },
0224     {
0225         .name = "Hostless_UL5 DAI",
0226         .id = MT8186_DAI_HOSTLESS_UL5,
0227         .capture = {
0228             .stream_name = "Hostless_UL5 UL",
0229             .channels_min = 1,
0230             .channels_max = 12,
0231             .rates = MTK_HOSTLESS_RATES,
0232             .formats = MTK_HOSTLESS_FORMATS,
0233         },
0234         .ops = &mtk_dai_hostless_ops,
0235     },
0236     {
0237         .name = "Hostless_UL6 DAI",
0238         .id = MT8186_DAI_HOSTLESS_UL6,
0239         .capture = {
0240             .stream_name = "Hostless_UL6 UL",
0241             .channels_min = 1,
0242             .channels_max = 2,
0243             .rates = MTK_HOSTLESS_RATES,
0244             .formats = MTK_HOSTLESS_FORMATS,
0245         },
0246         .ops = &mtk_dai_hostless_ops,
0247     },
0248     {
0249         .name = "Hostless HW Gain AAudio DAI",
0250         .id = MT8186_DAI_HOSTLESS_HW_GAIN_AAUDIO,
0251         .capture = {
0252             .stream_name = "Hostless HW Gain AAudio In",
0253             .channels_min = 1,
0254             .channels_max = 2,
0255             .rates = MTK_HOSTLESS_RATES,
0256             .formats = MTK_HOSTLESS_FORMATS,
0257         },
0258         .ops = &mtk_dai_hostless_ops,
0259     },
0260     {
0261         .name = "Hostless SRC AAudio DAI",
0262         .id = MT8186_DAI_HOSTLESS_SRC_AAUDIO,
0263         .playback = {
0264             .stream_name = "Hostless SRC AAudio DL",
0265             .channels_min = 1,
0266             .channels_max = 2,
0267             .rates = MTK_HOSTLESS_RATES,
0268             .formats = MTK_HOSTLESS_FORMATS,
0269         },
0270         .capture = {
0271             .stream_name = "Hostless SRC AAudio UL",
0272             .channels_min = 1,
0273             .channels_max = 2,
0274             .rates = MTK_HOSTLESS_RATES,
0275             .formats = MTK_HOSTLESS_FORMATS,
0276         },
0277         .ops = &mtk_dai_hostless_ops,
0278     },
0279 };
0280 
0281 int mt8186_dai_hostless_register(struct mtk_base_afe *afe)
0282 {
0283     struct mtk_base_afe_dai *dai;
0284 
0285     dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
0286     if (!dai)
0287         return -ENOMEM;
0288 
0289     list_add(&dai->list, &afe->sub_dais);
0290 
0291     dai->dai_drivers = mtk_dai_hostless_driver;
0292     dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_hostless_driver);
0293 
0294     dai->dapm_routes = mtk_dai_hostless_routes;
0295     dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_hostless_routes);
0296 
0297     return 0;
0298 }