~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/mediatek/mt8188/mt8188-dai-adda.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * MediaTek ALSA SoC Audio DAI ADDA Control
  4  *
  5  * Copyright (c) 2022 MediaTek Inc.
  6  * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
  7  *         Trevor Wu <trevor.wu@mediatek.com>
  8  *         Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
  9  */
 10 
 11 #include <linux/bitfield.h>
 12 #include <linux/delay.h>
 13 #include <linux/regmap.h>
 14 #include "mt8188-afe-clk.h"
 15 #include "mt8188-afe-common.h"
 16 #include "mt8188-reg.h"
 17 #include "../common/mtk-dai-adda-common.h"
 18 
 19 #define ADDA_HIRES_THRES 48000
 20 
 21 enum {
 22         SUPPLY_SEQ_ADDA_DL_ON,
 23         SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 24         SUPPLY_SEQ_ADDA_UL_ON,
 25         SUPPLY_SEQ_ADDA_AFE_ON,
 26 };
 27 
 28 struct mtk_dai_adda_priv {
 29         bool hires_required;
 30 };
 31 
 32 static int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
 33 {
 34         struct mt8188_afe_private *afe_priv = afe->platform_priv;
 35         struct mtkaif_param *param = &afe_priv->mtkaif_params;
 36         int delay_data;
 37         int delay_cycle;
 38         unsigned int mask = 0;
 39         unsigned int val = 0;
 40 
 41         /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
 42         regmap_set_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
 43                         MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
 44 
 45         regmap_set_bits(afe->regmap, AFE_AUD_PAD_TOP, RG_RX_PROTOCOL2);
 46 
 47         if (!param->mtkaif_calibration_ok) {
 48                 dev_info(afe->dev, "%s(), calibration fail\n",  __func__);
 49                 return 0;
 50         }
 51 
 52         /* set delay for ch1, ch2 */
 53         if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
 54             param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
 55                 delay_data = DELAY_DATA_MISO1;
 56                 delay_cycle =
 57                         param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] -
 58                         param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
 59         } else {
 60                 delay_data = DELAY_DATA_MISO0;
 61                 delay_cycle =
 62                         param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] -
 63                         param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
 64         }
 65 
 66         val = 0;
 67         mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
 68         val |= FIELD_PREP(MTKAIF_RXIF_DELAY_CYCLE_MASK, delay_cycle);
 69         val |= FIELD_PREP(MTKAIF_RXIF_DELAY_DATA, delay_data);
 70         regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
 71 
 72         return 0;
 73 }
 74 
 75 static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
 76                                      struct snd_kcontrol *kcontrol,
 77                                      int event)
 78 {
 79         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 80         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 81 
 82         dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
 83                 __func__, w->name, event);
 84 
 85         switch (event) {
 86         case SND_SOC_DAPM_PRE_PMU:
 87                 mt8188_adda_mtkaif_init(afe);
 88                 break;
 89         default:
 90                 break;
 91         }
 92 
 93         return 0;
 94 }
 95 
 96 static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
 97                              struct snd_kcontrol *kcontrol,
 98                              int event)
 99 {
100         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
101         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
102 
103         dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
104                 __func__, w->name, event);
105 
106         switch (event) {
107         case SND_SOC_DAPM_POST_PMD:
108                 /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
109                 usleep_range(125, 135);
110                 break;
111         default:
112                 break;
113         }
114 
115         return 0;
116 }
117 
118 static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool dmic)
119 {
120         unsigned int reg = AFE_ADDA_UL_SRC_CON0;
121         unsigned int val;
122 
123         val = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
124                UL_MODE_3P25M_CH2_CTL);
125 
126         /* turn on dmic, ch1, ch2 */
127         if (dmic)
128                 regmap_set_bits(afe->regmap, reg, val);
129         else
130                 regmap_clear_bits(afe->regmap, reg, val);
131 }
132 
133 static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
134                              struct snd_kcontrol *kcontrol,
135                              int event)
136 {
137         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
138         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
139         struct mt8188_afe_private *afe_priv = afe->platform_priv;
140         struct mtkaif_param *param = &afe_priv->mtkaif_params;
141 
142         dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
143                 __func__, w->name, event);
144 
145         switch (event) {
146         case SND_SOC_DAPM_PRE_PMU:
147                 mtk_adda_ul_mictype(afe, param->mtkaif_dmic_on);
148                 break;
149         case SND_SOC_DAPM_POST_PMD:
150                 /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
151                 usleep_range(125, 135);
152                 break;
153         default:
154                 break;
155         }
156 
157         return 0;
158 }
159 
160 static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
161                                                        const char *name)
162 {
163         struct mt8188_afe_private *afe_priv = afe->platform_priv;
164 
165         if (strstr(name, "aud_adc_hires"))
166                 return afe_priv->dai_priv[MT8188_AFE_IO_UL_SRC];
167         else if (strstr(name, "aud_dac_hires"))
168                 return afe_priv->dai_priv[MT8188_AFE_IO_DL_SRC];
169         else
170                 return NULL;
171 }
172 
173 static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
174                                       struct snd_soc_dapm_widget *sink)
175 {
176         struct snd_soc_dapm_widget *w = source;
177         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
178         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
179         struct mtk_dai_adda_priv *adda_priv;
180 
181         adda_priv = get_adda_priv_by_name(afe, w->name);
182 
183         if (!adda_priv) {
184                 dev_dbg(afe->dev, "adda_priv == NULL");
185                 return 0;
186         }
187 
188         return (adda_priv->hires_required) ? 1 : 0;
189 }
190 
191 static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
192         SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
193         SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
194         SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
195         SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
196         SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
197 };
198 
199 static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
200         SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
201         SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
202         SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
203         SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
204         SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
205 };
206 
207 static const char * const adda_dlgain_mux_map[] = {
208         "Bypass", "Connect",
209 };
210 
211 static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
212                             SND_SOC_NOPM, 0,
213                             adda_dlgain_mux_map);
214 
215 static const struct snd_kcontrol_new adda_dlgain_mux_control =
216         SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
217 
218 static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
219         SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
220         SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
221 
222         SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
223                            mtk_dai_adda_o176_mix,
224                            ARRAY_SIZE(mtk_dai_adda_o176_mix)),
225         SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
226                            mtk_dai_adda_o177_mix,
227                            ARRAY_SIZE(mtk_dai_adda_o177_mix)),
228 
229         SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
230                               AFE_ADDA_UL_DL_CON0,
231                               ADDA_AFE_ON_SHIFT, 0,
232                               NULL,
233                               0),
234 
235         SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
236                               AFE_ADDA_DL_SRC2_CON0,
237                               DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
238                               mtk_adda_dl_event,
239                               SND_SOC_DAPM_POST_PMD),
240 
241         SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
242                               AFE_ADDA_UL_SRC_CON0,
243                               UL_SRC_ON_TMP_CTL_SHIFT, 0,
244                               mtk_adda_ul_event,
245                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
246 
247         SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
248                               SND_SOC_NOPM,
249                               0, 0,
250                               mtk_adda_mtkaif_cfg_event,
251                               SND_SOC_DAPM_PRE_PMU),
252 
253         SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
254                          &adda_dlgain_mux_control),
255 
256         SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
257                          DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
258 
259         SND_SOC_DAPM_INPUT("ADDA_INPUT"),
260         SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
261 
262         SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
263         SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
264         SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
265         SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
266 };
267 
268 static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
269         {"ADDA Capture", NULL, "ADDA Enable"},
270         {"ADDA Capture", NULL, "ADDA Capture Enable"},
271         {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
272         {"ADDA Capture", NULL, "aud_adc"},
273         {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
274 
275         {"I168", NULL, "ADDA Capture"},
276         {"I169", NULL, "ADDA Capture"},
277 
278         {"ADDA Playback", NULL, "ADDA Enable"},
279         {"ADDA Playback", NULL, "ADDA Playback Enable"},
280         {"ADDA Playback", NULL, "aud_dac"},
281         {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
282 
283         {"DL_GAIN", NULL, "O176"},
284         {"DL_GAIN", NULL, "O177"},
285 
286         {"DL_GAIN_MUX", "Bypass", "O176"},
287         {"DL_GAIN_MUX", "Bypass", "O177"},
288         {"DL_GAIN_MUX", "Connect", "DL_GAIN"},
289 
290         {"ADDA Playback", NULL, "DL_GAIN_MUX"},
291 
292         {"O176", "I000 Switch", "I000"},
293         {"O177", "I001 Switch", "I001"},
294 
295         {"O176", "I002 Switch", "I002"},
296         {"O177", "I003 Switch", "I003"},
297 
298         {"O176", "I020 Switch", "I020"},
299         {"O177", "I021 Switch", "I021"},
300 
301         {"O176", "I022 Switch", "I022"},
302         {"O177", "I023 Switch", "I023"},
303 
304         {"O176", "I070 Switch", "I070"},
305         {"O177", "I071 Switch", "I071"},
306 
307         {"ADDA Capture", NULL, "ADDA_INPUT"},
308         {"ADDA_OUTPUT", NULL, "ADDA Playback"},
309 };
310 
311 static int mt8188_adda_dmic_get(struct snd_kcontrol *kcontrol,
312                                 struct snd_ctl_elem_value *ucontrol)
313 {
314         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
315         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
316         struct mt8188_afe_private *afe_priv = afe->platform_priv;
317         struct mtkaif_param *param = &afe_priv->mtkaif_params;
318 
319         ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
320         return 0;
321 }
322 
323 static int mt8188_adda_dmic_set(struct snd_kcontrol *kcontrol,
324                                 struct snd_ctl_elem_value *ucontrol)
325 {
326         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
327         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
328         struct mt8188_afe_private *afe_priv = afe->platform_priv;
329         struct mtkaif_param *param = &afe_priv->mtkaif_params;
330         int dmic_on;
331 
332         dmic_on = !!ucontrol->value.integer.value[0];
333 
334         dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
335                 __func__, kcontrol->id.name, dmic_on);
336 
337         if (param->mtkaif_dmic_on == dmic_on)
338                 return 0;
339 
340         param->mtkaif_dmic_on = dmic_on;
341         return 1;
342 }
343 
344 static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
345         SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
346                    DL_2_GAIN_CTL_PRE_SHIFT, 65535, 0),
347         SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0,
348                             mt8188_adda_dmic_get, mt8188_adda_dmic_set),
349 };
350 
351 static int mtk_dai_da_configure(struct mtk_base_afe *afe,
352                                 unsigned int rate, int id)
353 {
354         unsigned int val = 0;
355         unsigned int mask = 0;
356 
357         /* set sampling rate */
358         mask |= DL_2_INPUT_MODE_CTL_MASK;
359         val |= FIELD_PREP(DL_2_INPUT_MODE_CTL_MASK,
360                           mtk_adda_dl_rate_transform(afe, rate));
361 
362         /* turn off saturation */
363         mask |= DL_2_CH1_SATURATION_EN_CTL;
364         mask |= DL_2_CH2_SATURATION_EN_CTL;
365 
366         /* turn off mute function */
367         mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
368         mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
369         val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
370         val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
371 
372         /* set voice input data if input sample rate is 8k or 16k */
373         mask |= DL_2_VOICE_MODE_CTL_PRE;
374         if (rate == 8000 || rate == 16000)
375                 val |= DL_2_VOICE_MODE_CTL_PRE;
376 
377         regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
378 
379         /* new 2nd sdm */
380         regmap_set_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON,
381                         DL_USE_NEW_2ND_SDM);
382 
383         return 0;
384 }
385 
386 static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
387                                 unsigned int rate, int id)
388 {
389         unsigned int val;
390         unsigned int mask;
391 
392         mask = UL_VOICE_MODE_CTL_MASK;
393         val = FIELD_PREP(UL_VOICE_MODE_CTL_MASK,
394                          mtk_adda_ul_rate_transform(afe, rate));
395 
396         regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
397                            mask, val);
398         return 0;
399 }
400 
401 static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
402                                   struct snd_pcm_hw_params *params,
403                                   struct snd_soc_dai *dai)
404 {
405         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
406         struct mt8188_afe_private *afe_priv = afe->platform_priv;
407         struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
408         unsigned int rate = params_rate(params);
409         int id = dai->id;
410         int ret = 0;
411 
412         dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
413                 __func__, id, substream->stream, rate);
414 
415         adda_priv->hires_required = (rate > ADDA_HIRES_THRES);
416 
417         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
418                 ret = mtk_dai_da_configure(afe, rate, id);
419         else
420                 ret = mtk_dai_ad_configure(afe, rate, id);
421 
422         return ret;
423 }
424 
425 static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
426         .hw_params = mtk_dai_adda_hw_params,
427 };
428 
429 /* dai driver */
430 #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
431                                  SNDRV_PCM_RATE_96000 |\
432                                  SNDRV_PCM_RATE_192000)
433 
434 #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
435                                 SNDRV_PCM_RATE_16000 |\
436                                 SNDRV_PCM_RATE_32000 |\
437                                 SNDRV_PCM_RATE_48000 |\
438                                 SNDRV_PCM_RATE_96000 |\
439                                 SNDRV_PCM_RATE_192000)
440 
441 #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
442                           SNDRV_PCM_FMTBIT_S24_LE |\
443                           SNDRV_PCM_FMTBIT_S32_LE)
444 
445 static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
446         {
447                 .name = "DL_SRC",
448                 .id = MT8188_AFE_IO_DL_SRC,
449                 .playback = {
450                         .stream_name = "ADDA Playback",
451                         .channels_min = 1,
452                         .channels_max = 2,
453                         .rates = MTK_ADDA_PLAYBACK_RATES,
454                         .formats = MTK_ADDA_FORMATS,
455                 },
456                 .ops = &mtk_dai_adda_ops,
457         },
458         {
459                 .name = "UL_SRC",
460                 .id = MT8188_AFE_IO_UL_SRC,
461                 .capture = {
462                         .stream_name = "ADDA Capture",
463                         .channels_min = 1,
464                         .channels_max = 2,
465                         .rates = MTK_ADDA_CAPTURE_RATES,
466                         .formats = MTK_ADDA_FORMATS,
467                 },
468                 .ops = &mtk_dai_adda_ops,
469         },
470 };
471 
472 static int init_adda_priv_data(struct mtk_base_afe *afe)
473 {
474         struct mt8188_afe_private *afe_priv = afe->platform_priv;
475         struct mtk_dai_adda_priv *adda_priv;
476         int adda_dai_list[] = {MT8188_AFE_IO_DL_SRC, MT8188_AFE_IO_UL_SRC};
477         int i;
478 
479         for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
480                 adda_priv = devm_kzalloc(afe->dev,
481                                          sizeof(struct mtk_dai_adda_priv),
482                                          GFP_KERNEL);
483                 if (!adda_priv)
484                         return -ENOMEM;
485 
486                 afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
487         }
488 
489         return 0;
490 }
491 
492 int mt8188_dai_adda_register(struct mtk_base_afe *afe)
493 {
494         struct mtk_base_afe_dai *dai;
495 
496         dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
497         if (!dai)
498                 return -ENOMEM;
499 
500         list_add(&dai->list, &afe->sub_dais);
501 
502         dai->dai_drivers = mtk_dai_adda_driver;
503         dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
504 
505         dai->dapm_widgets = mtk_dai_adda_widgets;
506         dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
507         dai->dapm_routes = mtk_dai_adda_routes;
508         dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
509         dai->controls = mtk_dai_adda_controls;
510         dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
511 
512         return init_adda_priv_data(afe);
513 }
514 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php