0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/regmap.h>
0011 #include <sound/pcm_params.h>
0012 #include "mt8195-afe-clk.h"
0013 #include "mt8195-afe-common.h"
0014 #include "mt8195-reg.h"
0015
0016 enum {
0017 MTK_DAI_PCM_FMT_I2S,
0018 MTK_DAI_PCM_FMT_EIAJ,
0019 MTK_DAI_PCM_FMT_MODEA,
0020 MTK_DAI_PCM_FMT_MODEB,
0021 };
0022
0023 enum {
0024 MTK_DAI_PCM_CLK_A1SYS,
0025 MTK_DAI_PCM_CLK_A2SYS,
0026 MTK_DAI_PCM_CLK_26M_48K,
0027 MTK_DAI_PCM_CLK_26M_441K,
0028 };
0029
0030 struct mtk_dai_pcm_rate {
0031 unsigned int rate;
0032 unsigned int reg_value;
0033 };
0034
0035 struct mtk_dai_pcmif_priv {
0036 unsigned int slave_mode;
0037 unsigned int lrck_inv;
0038 unsigned int bck_inv;
0039 unsigned int format;
0040 };
0041
0042 static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
0043 { .rate = 8000, .reg_value = 0, },
0044 { .rate = 16000, .reg_value = 1, },
0045 { .rate = 32000, .reg_value = 2, },
0046 { .rate = 48000, .reg_value = 3, },
0047 { .rate = 11025, .reg_value = 1, },
0048 { .rate = 22050, .reg_value = 2, },
0049 { .rate = 44100, .reg_value = 3, },
0050 };
0051
0052 static int mtk_dai_pcm_mode(unsigned int rate)
0053 {
0054 int i;
0055
0056 for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
0057 if (mtk_dai_pcm_rates[i].rate == rate)
0058 return mtk_dai_pcm_rates[i].reg_value;
0059
0060 return -EINVAL;
0061 }
0062
0063 static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
0064 SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
0065 SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
0066 };
0067
0068 static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
0069 SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
0070 SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
0071 };
0072
0073 static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
0074 SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
0075 SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
0076 SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
0077 mtk_dai_pcm_o000_mix,
0078 ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
0079 SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
0080 mtk_dai_pcm_o001_mix,
0081 ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
0082
0083 SND_SOC_DAPM_SUPPLY("PCM_EN", PCM_INTF_CON1,
0084 PCM_INTF_CON1_PCM_EN_SHIFT, 0, NULL, 0),
0085
0086 SND_SOC_DAPM_INPUT("PCM1_INPUT"),
0087 SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
0088
0089 SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc11"),
0090 SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc12"),
0091 SND_SOC_DAPM_CLOCK_SUPPLY("aud_pcmif"),
0092 };
0093
0094 static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
0095 {"I002", NULL, "PCM1 Capture"},
0096 {"I003", NULL, "PCM1 Capture"},
0097
0098 {"O000", "I000 Switch", "I000"},
0099 {"O001", "I001 Switch", "I001"},
0100
0101 {"O000", "I070 Switch", "I070"},
0102 {"O001", "I071 Switch", "I071"},
0103
0104 {"PCM1 Playback", NULL, "O000"},
0105 {"PCM1 Playback", NULL, "O001"},
0106
0107 {"PCM1 Playback", NULL, "PCM_EN"},
0108 {"PCM1 Playback", NULL, "aud_asrc12"},
0109 {"PCM1 Playback", NULL, "aud_pcmif"},
0110
0111 {"PCM1 Capture", NULL, "PCM_EN"},
0112 {"PCM1 Capture", NULL, "aud_asrc11"},
0113 {"PCM1 Capture", NULL, "aud_pcmif"},
0114
0115 {"PCM1_OUTPUT", NULL, "PCM1 Playback"},
0116 {"PCM1 Capture", NULL, "PCM1_INPUT"},
0117 };
0118
0119 static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
0120 struct snd_soc_dai *dai)
0121 {
0122 struct snd_pcm_runtime * const runtime = substream->runtime;
0123 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0124 struct mt8195_afe_private *afe_priv = afe->platform_priv;
0125 struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
0126 unsigned int slave_mode = pcmif_priv->slave_mode;
0127 unsigned int lrck_inv = pcmif_priv->lrck_inv;
0128 unsigned int bck_inv = pcmif_priv->bck_inv;
0129 unsigned int fmt = pcmif_priv->format;
0130 unsigned int bit_width = dai->sample_bits;
0131 unsigned int val = 0;
0132 unsigned int mask = 0;
0133 int fs = 0;
0134 int mode = 0;
0135
0136
0137 fs = mt8195_afe_fs_timing(runtime->rate);
0138 if (fs < 0)
0139 return -EINVAL;
0140 val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
0141 mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
0142
0143
0144 if (runtime->rate % 8000)
0145 val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
0146 else
0147 val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
0148 mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
0149
0150 regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
0151
0152 val = 0;
0153 mask = 0;
0154
0155
0156 mode = mtk_dai_pcm_mode(runtime->rate);
0157 if (mode < 0)
0158 return -EINVAL;
0159 val |= PCM_INTF_CON1_PCM_MODE(mode);
0160 mask |= PCM_INTF_CON1_PCM_MODE_MASK;
0161
0162
0163 val |= PCM_INTF_CON1_PCM_FMT(fmt);
0164 mask |= PCM_INTF_CON1_PCM_FMT_MASK;
0165
0166
0167 if (fmt == MTK_DAI_PCM_FMT_MODEA ||
0168 fmt == MTK_DAI_PCM_FMT_MODEB)
0169 val |= PCM_INTF_CON1_SYNC_LENGTH(1);
0170 else
0171 val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
0172 mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
0173
0174
0175 if (bit_width > 16) {
0176 val |= PCM_INTF_CON1_PCM_24BIT;
0177 val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
0178 } else {
0179 val |= PCM_INTF_CON1_PCM_16BIT;
0180 val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
0181 }
0182 mask |= PCM_INTF_CON1_PCM_BIT_MASK;
0183 mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
0184
0185
0186 if (!slave_mode) {
0187 val |= PCM_INTF_CON1_PCM_MASTER;
0188
0189 if (lrck_inv)
0190 val |= PCM_INTF_CON1_SYNC_OUT_INV;
0191 if (bck_inv)
0192 val |= PCM_INTF_CON1_BCLK_OUT_INV;
0193 mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
0194 } else {
0195 val |= PCM_INTF_CON1_PCM_SLAVE;
0196
0197 if (lrck_inv)
0198 val |= PCM_INTF_CON1_SYNC_IN_INV;
0199 if (bck_inv)
0200 val |= PCM_INTF_CON1_BCLK_IN_INV;
0201 mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
0202
0203
0204 }
0205 mask |= PCM_INTF_CON1_PCM_M_S_MASK;
0206
0207 regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
0208
0209 return 0;
0210 }
0211
0212
0213 static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
0214 struct snd_soc_dai *dai)
0215 {
0216 dev_dbg(dai->dev, "%s(), id %d, stream %d, widget active p %d, c %d\n",
0217 __func__, dai->id, substream->stream,
0218 dai->playback_widget->active, dai->capture_widget->active);
0219
0220 if (dai->playback_widget->active || dai->capture_widget->active)
0221 return 0;
0222
0223 return mtk_dai_pcm_configure(substream, dai);
0224 }
0225
0226 static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0227 {
0228 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0229 struct mt8195_afe_private *afe_priv = afe->platform_priv;
0230 struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
0231
0232 dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
0233
0234 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0235 case SND_SOC_DAIFMT_I2S:
0236 pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
0237 break;
0238 case SND_SOC_DAIFMT_DSP_A:
0239 pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
0240 break;
0241 case SND_SOC_DAIFMT_DSP_B:
0242 pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
0243 break;
0244 default:
0245 return -EINVAL;
0246 }
0247
0248 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0249 case SND_SOC_DAIFMT_NB_NF:
0250 pcmif_priv->bck_inv = 0;
0251 pcmif_priv->lrck_inv = 0;
0252 break;
0253 case SND_SOC_DAIFMT_NB_IF:
0254 pcmif_priv->bck_inv = 0;
0255 pcmif_priv->lrck_inv = 1;
0256 break;
0257 case SND_SOC_DAIFMT_IB_NF:
0258 pcmif_priv->bck_inv = 1;
0259 pcmif_priv->lrck_inv = 0;
0260 break;
0261 case SND_SOC_DAIFMT_IB_IF:
0262 pcmif_priv->bck_inv = 1;
0263 pcmif_priv->lrck_inv = 1;
0264 break;
0265 default:
0266 return -EINVAL;
0267 }
0268
0269 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0270 case SND_SOC_DAIFMT_BC_FC:
0271 pcmif_priv->slave_mode = 1;
0272 break;
0273 case SND_SOC_DAIFMT_BP_FP:
0274 pcmif_priv->slave_mode = 0;
0275 break;
0276 default:
0277 return -EINVAL;
0278 }
0279
0280 return 0;
0281 }
0282
0283 static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
0284 .prepare = mtk_dai_pcm_prepare,
0285 .set_fmt = mtk_dai_pcm_set_fmt,
0286 };
0287
0288
0289 #define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
0290
0291 #define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
0292 SNDRV_PCM_FMTBIT_S24_LE |\
0293 SNDRV_PCM_FMTBIT_S32_LE)
0294
0295 static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
0296 {
0297 .name = "PCM1",
0298 .id = MT8195_AFE_IO_PCM,
0299 .playback = {
0300 .stream_name = "PCM1 Playback",
0301 .channels_min = 1,
0302 .channels_max = 2,
0303 .rates = MTK_PCM_RATES,
0304 .formats = MTK_PCM_FORMATS,
0305 },
0306 .capture = {
0307 .stream_name = "PCM1 Capture",
0308 .channels_min = 1,
0309 .channels_max = 2,
0310 .rates = MTK_PCM_RATES,
0311 .formats = MTK_PCM_FORMATS,
0312 },
0313 .ops = &mtk_dai_pcm_ops,
0314 .symmetric_rate = 1,
0315 .symmetric_sample_bits = 1,
0316 },
0317 };
0318
0319 static int init_pcmif_priv_data(struct mtk_base_afe *afe)
0320 {
0321 struct mt8195_afe_private *afe_priv = afe->platform_priv;
0322 struct mtk_dai_pcmif_priv *pcmif_priv;
0323
0324 pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
0325 GFP_KERNEL);
0326 if (!pcmif_priv)
0327 return -ENOMEM;
0328
0329 afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv;
0330 return 0;
0331 }
0332
0333 int mt8195_dai_pcm_register(struct mtk_base_afe *afe)
0334 {
0335 struct mtk_base_afe_dai *dai;
0336
0337 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
0338 if (!dai)
0339 return -ENOMEM;
0340
0341 list_add(&dai->list, &afe->sub_dais);
0342
0343 dai->dai_drivers = mtk_dai_pcm_driver;
0344 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
0345
0346 dai->dapm_widgets = mtk_dai_pcm_widgets;
0347 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
0348 dai->dapm_routes = mtk_dai_pcm_routes;
0349 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
0350
0351 return init_pcmif_priv_data(afe);
0352 }