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

TOMOYO Linux Cross Reference
Linux/sound/soc/mediatek/mt8183/mt8183-dai-tdm.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/soc/mediatek/mt8183/mt8183-dai-tdm.c (Architecture sparc64) and /sound/soc/mediatek/mt8183/mt8183-dai-tdm.c (Architecture i386)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 //                                                  2 //
  3 // MediaTek ALSA SoC Audio DAI TDM Control          3 // MediaTek ALSA SoC Audio DAI TDM Control
  4 //                                                  4 //
  5 // Copyright (c) 2018 MediaTek Inc.                 5 // Copyright (c) 2018 MediaTek Inc.
  6 // Author: KaiChieh Chuang <kaichieh.chuang@me      6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
  7                                                     7 
  8 #include <linux/regmap.h>                           8 #include <linux/regmap.h>
  9 #include <sound/pcm_params.h>                       9 #include <sound/pcm_params.h>
 10 #include "mt8183-afe-clk.h"                        10 #include "mt8183-afe-clk.h"
 11 #include "mt8183-afe-common.h"                     11 #include "mt8183-afe-common.h"
 12 #include "mt8183-interconnection.h"                12 #include "mt8183-interconnection.h"
 13 #include "mt8183-reg.h"                            13 #include "mt8183-reg.h"
 14                                                    14 
 15 struct mtk_afe_tdm_priv {                          15 struct mtk_afe_tdm_priv {
 16         int bck_id;                                16         int bck_id;
 17         int bck_rate;                              17         int bck_rate;
 18         int tdm_out_mode;                          18         int tdm_out_mode;
 19         int bck_invert;                            19         int bck_invert;
 20         int lck_invert;                            20         int lck_invert;
 21         int mclk_id;                               21         int mclk_id;
 22         int mclk_multiple; /* according to sam     22         int mclk_multiple; /* according to sample rate */
 23         int mclk_rate;                             23         int mclk_rate;
 24         int mclk_apll;                             24         int mclk_apll;
 25 };                                                 25 };
 26                                                    26 
 27 enum {                                             27 enum {
 28         TDM_OUT_I2S = 0,                           28         TDM_OUT_I2S = 0,
 29         TDM_OUT_TDM = 1,                           29         TDM_OUT_TDM = 1,
 30 };                                                 30 };
 31                                                    31 
 32 enum {                                             32 enum {
 33         TDM_BCK_NON_INV = 0,                       33         TDM_BCK_NON_INV = 0,
 34         TDM_BCK_INV = 1,                           34         TDM_BCK_INV = 1,
 35 };                                                 35 };
 36                                                    36 
 37 enum {                                             37 enum {
 38         TDM_LCK_NON_INV = 0,                       38         TDM_LCK_NON_INV = 0,
 39         TDM_LCK_INV = 1,                           39         TDM_LCK_INV = 1,
 40 };                                                 40 };
 41                                                    41 
 42 enum {                                             42 enum {
 43         TDM_WLEN_16_BIT = 1,                       43         TDM_WLEN_16_BIT = 1,
 44         TDM_WLEN_32_BIT = 2,                       44         TDM_WLEN_32_BIT = 2,
 45 };                                                 45 };
 46                                                    46 
 47 enum {                                             47 enum {
 48         TDM_CHANNEL_BCK_16 = 0,                    48         TDM_CHANNEL_BCK_16 = 0,
 49         TDM_CHANNEL_BCK_24 = 1,                    49         TDM_CHANNEL_BCK_24 = 1,
 50         TDM_CHANNEL_BCK_32 = 2,                    50         TDM_CHANNEL_BCK_32 = 2,
 51 };                                                 51 };
 52                                                    52 
 53 enum {                                             53 enum {
 54         TDM_CHANNEL_NUM_2 = 0,                     54         TDM_CHANNEL_NUM_2 = 0,
 55         TDM_CHANNEL_NUM_4 = 1,                     55         TDM_CHANNEL_NUM_4 = 1,
 56         TDM_CHANNEL_NUM_8 = 2,                     56         TDM_CHANNEL_NUM_8 = 2,
 57 };                                                 57 };
 58                                                    58 
 59 enum  {                                            59 enum  {
 60         TDM_CH_START_O30_O31 = 0,                  60         TDM_CH_START_O30_O31 = 0,
 61         TDM_CH_START_O32_O33,                      61         TDM_CH_START_O32_O33,
 62         TDM_CH_START_O34_O35,                      62         TDM_CH_START_O34_O35,
 63         TDM_CH_START_O36_O37,                      63         TDM_CH_START_O36_O37,
 64         TDM_CH_ZERO,                               64         TDM_CH_ZERO,
 65 };                                                 65 };
 66                                                    66 
 67 enum {                                             67 enum {
 68         HDMI_BIT_WIDTH_16_BIT = 0,                 68         HDMI_BIT_WIDTH_16_BIT = 0,
 69         HDMI_BIT_WIDTH_32_BIT = 1,                 69         HDMI_BIT_WIDTH_32_BIT = 1,
 70 };                                                 70 };
 71                                                    71 
 72 static unsigned int get_hdmi_wlen(snd_pcm_form     72 static unsigned int get_hdmi_wlen(snd_pcm_format_t format)
 73 {                                                  73 {
 74         return snd_pcm_format_physical_width(f     74         return snd_pcm_format_physical_width(format) <= 16 ?
 75                HDMI_BIT_WIDTH_16_BIT : HDMI_BI     75                HDMI_BIT_WIDTH_16_BIT : HDMI_BIT_WIDTH_32_BIT;
 76 }                                                  76 }
 77                                                    77 
 78 static unsigned int get_tdm_wlen(snd_pcm_forma     78 static unsigned int get_tdm_wlen(snd_pcm_format_t format)
 79 {                                                  79 {
 80         return snd_pcm_format_physical_width(f     80         return snd_pcm_format_physical_width(format) <= 16 ?
 81                TDM_WLEN_16_BIT : TDM_WLEN_32_B     81                TDM_WLEN_16_BIT : TDM_WLEN_32_BIT;
 82 }                                                  82 }
 83                                                    83 
 84 static unsigned int get_tdm_channel_bck(snd_pc     84 static unsigned int get_tdm_channel_bck(snd_pcm_format_t format)
 85 {                                                  85 {
 86         return snd_pcm_format_physical_width(f     86         return snd_pcm_format_physical_width(format) <= 16 ?
 87                TDM_CHANNEL_BCK_16 : TDM_CHANNE     87                TDM_CHANNEL_BCK_16 : TDM_CHANNEL_BCK_32;
 88 }                                                  88 }
 89                                                    89 
 90 static unsigned int get_tdm_lrck_width(snd_pcm     90 static unsigned int get_tdm_lrck_width(snd_pcm_format_t format)
 91 {                                                  91 {
 92         return snd_pcm_format_physical_width(f     92         return snd_pcm_format_physical_width(format) - 1;
 93 }                                                  93 }
 94                                                    94 
 95 static unsigned int get_tdm_ch(unsigned int ch     95 static unsigned int get_tdm_ch(unsigned int ch)
 96 {                                                  96 {
 97         switch (ch) {                              97         switch (ch) {
 98         case 1:                                    98         case 1:
 99         case 2:                                    99         case 2:
100                 return TDM_CHANNEL_NUM_2;         100                 return TDM_CHANNEL_NUM_2;
101         case 3:                                   101         case 3:
102         case 4:                                   102         case 4:
103                 return TDM_CHANNEL_NUM_4;         103                 return TDM_CHANNEL_NUM_4;
104         case 5:                                   104         case 5:
105         case 6:                                   105         case 6:
106         case 7:                                   106         case 7:
107         case 8:                                   107         case 8:
108         default:                                  108         default:
109                 return TDM_CHANNEL_NUM_8;         109                 return TDM_CHANNEL_NUM_8;
110         }                                         110         }
111 }                                                 111 }
112                                                   112 
113 static unsigned int get_tdm_ch_fixup(unsigned     113 static unsigned int get_tdm_ch_fixup(unsigned int channels)
114 {                                                 114 {
115         if (channels > 4)                         115         if (channels > 4)
116                 return 8;                         116                 return 8;
117         else if (channels > 2)                    117         else if (channels > 2)
118                 return 4;                         118                 return 4;
119         else                                      119         else
120                 return 2;                         120                 return 2;
121 }                                                 121 }
122                                                   122 
123 static unsigned int get_tdm_ch_per_sdata(unsig    123 static unsigned int get_tdm_ch_per_sdata(unsigned int mode,
124                                          unsig    124                                          unsigned int channels)
125 {                                                 125 {
126         if (mode == TDM_OUT_TDM)                  126         if (mode == TDM_OUT_TDM)
127                 return get_tdm_ch_fixup(channe    127                 return get_tdm_ch_fixup(channels);
128         else                                      128         else
129                 return 2;                         129                 return 2;
130 }                                                 130 }
131                                                   131 
132 /* interconnection */                             132 /* interconnection */
133 enum {                                            133 enum {
134         HDMI_CONN_CH0 = 0,                        134         HDMI_CONN_CH0 = 0,
135         HDMI_CONN_CH1,                            135         HDMI_CONN_CH1,
136         HDMI_CONN_CH2,                            136         HDMI_CONN_CH2,
137         HDMI_CONN_CH3,                            137         HDMI_CONN_CH3,
138         HDMI_CONN_CH4,                            138         HDMI_CONN_CH4,
139         HDMI_CONN_CH5,                            139         HDMI_CONN_CH5,
140         HDMI_CONN_CH6,                            140         HDMI_CONN_CH6,
141         HDMI_CONN_CH7,                            141         HDMI_CONN_CH7,
142 };                                                142 };
143                                                   143 
144 static const char *const hdmi_conn_mux_map[] =    144 static const char *const hdmi_conn_mux_map[] = {
145         "CH0", "CH1", "CH2", "CH3",               145         "CH0", "CH1", "CH2", "CH3",
146         "CH4", "CH5", "CH6", "CH7",               146         "CH4", "CH5", "CH6", "CH7",
147 };                                                147 };
148                                                   148 
149 static int hdmi_conn_mux_map_value[] = {          149 static int hdmi_conn_mux_map_value[] = {
150         HDMI_CONN_CH0,                            150         HDMI_CONN_CH0,
151         HDMI_CONN_CH1,                            151         HDMI_CONN_CH1,
152         HDMI_CONN_CH2,                            152         HDMI_CONN_CH2,
153         HDMI_CONN_CH3,                            153         HDMI_CONN_CH3,
154         HDMI_CONN_CH4,                            154         HDMI_CONN_CH4,
155         HDMI_CONN_CH5,                            155         HDMI_CONN_CH5,
156         HDMI_CONN_CH6,                            156         HDMI_CONN_CH6,
157         HDMI_CONN_CH7,                            157         HDMI_CONN_CH7,
158 };                                                158 };
159                                                   159 
160 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux    160 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum,
161                                   AFE_HDMI_CON    161                                   AFE_HDMI_CONN0,
162                                   HDMI_O_0_SFT    162                                   HDMI_O_0_SFT,
163                                   HDMI_O_0_MAS    163                                   HDMI_O_0_MASK,
164                                   hdmi_conn_mu    164                                   hdmi_conn_mux_map,
165                                   hdmi_conn_mu    165                                   hdmi_conn_mux_map_value);
166                                                   166 
167 static const struct snd_kcontrol_new hdmi_ch0_    167 static const struct snd_kcontrol_new hdmi_ch0_mux_control =
168         SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0    168         SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum);
169                                                   169 
170 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux    170 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum,
171                                   AFE_HDMI_CON    171                                   AFE_HDMI_CONN0,
172                                   HDMI_O_1_SFT    172                                   HDMI_O_1_SFT,
173                                   HDMI_O_1_MAS    173                                   HDMI_O_1_MASK,
174                                   hdmi_conn_mu    174                                   hdmi_conn_mux_map,
175                                   hdmi_conn_mu    175                                   hdmi_conn_mux_map_value);
176                                                   176 
177 static const struct snd_kcontrol_new hdmi_ch1_    177 static const struct snd_kcontrol_new hdmi_ch1_mux_control =
178         SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1    178         SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum);
179                                                   179 
180 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux    180 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum,
181                                   AFE_HDMI_CON    181                                   AFE_HDMI_CONN0,
182                                   HDMI_O_2_SFT    182                                   HDMI_O_2_SFT,
183                                   HDMI_O_2_MAS    183                                   HDMI_O_2_MASK,
184                                   hdmi_conn_mu    184                                   hdmi_conn_mux_map,
185                                   hdmi_conn_mu    185                                   hdmi_conn_mux_map_value);
186                                                   186 
187 static const struct snd_kcontrol_new hdmi_ch2_    187 static const struct snd_kcontrol_new hdmi_ch2_mux_control =
188         SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2    188         SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum);
189                                                   189 
190 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux    190 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum,
191                                   AFE_HDMI_CON    191                                   AFE_HDMI_CONN0,
192                                   HDMI_O_3_SFT    192                                   HDMI_O_3_SFT,
193                                   HDMI_O_3_MAS    193                                   HDMI_O_3_MASK,
194                                   hdmi_conn_mu    194                                   hdmi_conn_mux_map,
195                                   hdmi_conn_mu    195                                   hdmi_conn_mux_map_value);
196                                                   196 
197 static const struct snd_kcontrol_new hdmi_ch3_    197 static const struct snd_kcontrol_new hdmi_ch3_mux_control =
198         SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3    198         SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum);
199                                                   199 
200 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux    200 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum,
201                                   AFE_HDMI_CON    201                                   AFE_HDMI_CONN0,
202                                   HDMI_O_4_SFT    202                                   HDMI_O_4_SFT,
203                                   HDMI_O_4_MAS    203                                   HDMI_O_4_MASK,
204                                   hdmi_conn_mu    204                                   hdmi_conn_mux_map,
205                                   hdmi_conn_mu    205                                   hdmi_conn_mux_map_value);
206                                                   206 
207 static const struct snd_kcontrol_new hdmi_ch4_    207 static const struct snd_kcontrol_new hdmi_ch4_mux_control =
208         SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4    208         SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum);
209                                                   209 
210 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux    210 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum,
211                                   AFE_HDMI_CON    211                                   AFE_HDMI_CONN0,
212                                   HDMI_O_5_SFT    212                                   HDMI_O_5_SFT,
213                                   HDMI_O_5_MAS    213                                   HDMI_O_5_MASK,
214                                   hdmi_conn_mu    214                                   hdmi_conn_mux_map,
215                                   hdmi_conn_mu    215                                   hdmi_conn_mux_map_value);
216                                                   216 
217 static const struct snd_kcontrol_new hdmi_ch5_    217 static const struct snd_kcontrol_new hdmi_ch5_mux_control =
218         SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5    218         SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum);
219                                                   219 
220 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux    220 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum,
221                                   AFE_HDMI_CON    221                                   AFE_HDMI_CONN0,
222                                   HDMI_O_6_SFT    222                                   HDMI_O_6_SFT,
223                                   HDMI_O_6_MAS    223                                   HDMI_O_6_MASK,
224                                   hdmi_conn_mu    224                                   hdmi_conn_mux_map,
225                                   hdmi_conn_mu    225                                   hdmi_conn_mux_map_value);
226                                                   226 
227 static const struct snd_kcontrol_new hdmi_ch6_    227 static const struct snd_kcontrol_new hdmi_ch6_mux_control =
228         SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6    228         SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum);
229                                                   229 
230 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux    230 static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum,
231                                   AFE_HDMI_CON    231                                   AFE_HDMI_CONN0,
232                                   HDMI_O_7_SFT    232                                   HDMI_O_7_SFT,
233                                   HDMI_O_7_MAS    233                                   HDMI_O_7_MASK,
234                                   hdmi_conn_mu    234                                   hdmi_conn_mux_map,
235                                   hdmi_conn_mu    235                                   hdmi_conn_mux_map_value);
236                                                   236 
237 static const struct snd_kcontrol_new hdmi_ch7_    237 static const struct snd_kcontrol_new hdmi_ch7_mux_control =
238         SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7    238         SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum);
239                                                   239 
240 enum {                                            240 enum {
241         SUPPLY_SEQ_APLL,                          241         SUPPLY_SEQ_APLL,
242         SUPPLY_SEQ_TDM_MCK_EN,                    242         SUPPLY_SEQ_TDM_MCK_EN,
243         SUPPLY_SEQ_TDM_BCK_EN,                    243         SUPPLY_SEQ_TDM_BCK_EN,
244 };                                                244 };
245                                                   245 
246 static int mtk_tdm_bck_en_event(struct snd_soc    246 static int mtk_tdm_bck_en_event(struct snd_soc_dapm_widget *w,
247                                 struct snd_kco    247                                 struct snd_kcontrol *kcontrol,
248                                 int event)        248                                 int event)
249 {                                                 249 {
250         struct snd_soc_component *cmpnt = snd_    250         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
251         struct mtk_base_afe *afe = snd_soc_com    251         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
252         struct mt8183_afe_private *afe_priv =     252         struct mt8183_afe_private *afe_priv = afe->platform_priv;
253         struct mtk_afe_tdm_priv *tdm_priv = af    253         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
254                                                   254 
255         dev_info(cmpnt->dev, "%s(), name %s, e    255         dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
256                  __func__, w->name, event);       256                  __func__, w->name, event);
257                                                   257 
258         switch (event) {                          258         switch (event) {
259         case SND_SOC_DAPM_PRE_PMU:                259         case SND_SOC_DAPM_PRE_PMU:
260                 mt8183_mck_enable(afe, tdm_pri    260                 mt8183_mck_enable(afe, tdm_priv->bck_id, tdm_priv->bck_rate);
261                 break;                            261                 break;
262         case SND_SOC_DAPM_POST_PMD:               262         case SND_SOC_DAPM_POST_PMD:
263                 mt8183_mck_disable(afe, tdm_pr    263                 mt8183_mck_disable(afe, tdm_priv->bck_id);
264                 break;                            264                 break;
265         default:                                  265         default:
266                 break;                            266                 break;
267         }                                         267         }
268                                                   268 
269         return 0;                                 269         return 0;
270 }                                                 270 }
271                                                   271 
272 static int mtk_tdm_mck_en_event(struct snd_soc    272 static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w,
273                                 struct snd_kco    273                                 struct snd_kcontrol *kcontrol,
274                                 int event)        274                                 int event)
275 {                                                 275 {
276         struct snd_soc_component *cmpnt = snd_    276         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
277         struct mtk_base_afe *afe = snd_soc_com    277         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
278         struct mt8183_afe_private *afe_priv =     278         struct mt8183_afe_private *afe_priv = afe->platform_priv;
279         struct mtk_afe_tdm_priv *tdm_priv = af    279         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
280                                                   280 
281         dev_info(cmpnt->dev, "%s(), name %s, e    281         dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
282                  __func__, w->name, event);       282                  __func__, w->name, event);
283                                                   283 
284         switch (event) {                          284         switch (event) {
285         case SND_SOC_DAPM_PRE_PMU:                285         case SND_SOC_DAPM_PRE_PMU:
286                 mt8183_mck_enable(afe, tdm_pri    286                 mt8183_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate);
287                 break;                            287                 break;
288         case SND_SOC_DAPM_POST_PMD:               288         case SND_SOC_DAPM_POST_PMD:
289                 tdm_priv->mclk_rate = 0;          289                 tdm_priv->mclk_rate = 0;
290                 mt8183_mck_disable(afe, tdm_pr    290                 mt8183_mck_disable(afe, tdm_priv->mclk_id);
291                 break;                            291                 break;
292         default:                                  292         default:
293                 break;                            293                 break;
294         }                                         294         }
295                                                   295 
296         return 0;                                 296         return 0;
297 }                                                 297 }
298                                                   298 
299 static const struct snd_soc_dapm_widget mtk_da    299 static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = {
300         SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_S    300         SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0,
301                          &hdmi_ch0_mux_control    301                          &hdmi_ch0_mux_control),
302         SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_S    302         SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0,
303                          &hdmi_ch1_mux_control    303                          &hdmi_ch1_mux_control),
304         SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_S    304         SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0,
305                          &hdmi_ch2_mux_control    305                          &hdmi_ch2_mux_control),
306         SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_S    306         SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0,
307                          &hdmi_ch3_mux_control    307                          &hdmi_ch3_mux_control),
308         SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_S    308         SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0,
309                          &hdmi_ch4_mux_control    309                          &hdmi_ch4_mux_control),
310         SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_S    310         SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0,
311                          &hdmi_ch5_mux_control    311                          &hdmi_ch5_mux_control),
312         SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_S    312         SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0,
313                          &hdmi_ch6_mux_control    313                          &hdmi_ch6_mux_control),
314         SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_S    314         SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
315                          &hdmi_ch7_mux_control    315                          &hdmi_ch7_mux_control),
316                                                   316 
317         SND_SOC_DAPM_CLOCK_SUPPLY("aud_tdm_clk    317         SND_SOC_DAPM_CLOCK_SUPPLY("aud_tdm_clk"),
318                                                   318 
319         SND_SOC_DAPM_SUPPLY_S("TDM_BCK", SUPPL    319         SND_SOC_DAPM_SUPPLY_S("TDM_BCK", SUPPLY_SEQ_TDM_BCK_EN,
320                               SND_SOC_NOPM, 0,    320                               SND_SOC_NOPM, 0, 0,
321                               mtk_tdm_bck_en_e    321                               mtk_tdm_bck_en_event,
322                               SND_SOC_DAPM_PRE    322                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
323                                                   323 
324         SND_SOC_DAPM_SUPPLY_S("TDM_MCK", SUPPL    324         SND_SOC_DAPM_SUPPLY_S("TDM_MCK", SUPPLY_SEQ_TDM_MCK_EN,
325                               SND_SOC_NOPM, 0,    325                               SND_SOC_NOPM, 0, 0,
326                               mtk_tdm_mck_en_e    326                               mtk_tdm_mck_en_event,
327                               SND_SOC_DAPM_PRE    327                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
328 };                                                328 };
329                                                   329 
330 static int mtk_afe_tdm_apll_connect(struct snd    330 static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source,
331                                     struct snd    331                                     struct snd_soc_dapm_widget *sink)
332 {                                                 332 {
333         struct snd_soc_dapm_widget *w = sink;     333         struct snd_soc_dapm_widget *w = sink;
334         struct snd_soc_component *cmpnt = snd_    334         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
335         struct mtk_base_afe *afe = snd_soc_com    335         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
336         struct mt8183_afe_private *afe_priv =     336         struct mt8183_afe_private *afe_priv = afe->platform_priv;
337         struct mtk_afe_tdm_priv *tdm_priv = af    337         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[MT8183_DAI_TDM];
338         int cur_apll;                             338         int cur_apll;
339                                                   339 
340         /* which apll */                          340         /* which apll */
341         cur_apll = mt8183_get_apll_by_name(afe    341         cur_apll = mt8183_get_apll_by_name(afe, source->name);
342                                                   342 
343         return (tdm_priv->mclk_apll == cur_apl    343         return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0;
344 }                                                 344 }
345                                                   345 
346 static const struct snd_soc_dapm_route mtk_dai    346 static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = {
347         {"HDMI_CH0_MUX", "CH0", "HDMI"},          347         {"HDMI_CH0_MUX", "CH0", "HDMI"},
348         {"HDMI_CH0_MUX", "CH1", "HDMI"},          348         {"HDMI_CH0_MUX", "CH1", "HDMI"},
349         {"HDMI_CH0_MUX", "CH2", "HDMI"},          349         {"HDMI_CH0_MUX", "CH2", "HDMI"},
350         {"HDMI_CH0_MUX", "CH3", "HDMI"},          350         {"HDMI_CH0_MUX", "CH3", "HDMI"},
351         {"HDMI_CH0_MUX", "CH4", "HDMI"},          351         {"HDMI_CH0_MUX", "CH4", "HDMI"},
352         {"HDMI_CH0_MUX", "CH5", "HDMI"},          352         {"HDMI_CH0_MUX", "CH5", "HDMI"},
353         {"HDMI_CH0_MUX", "CH6", "HDMI"},          353         {"HDMI_CH0_MUX", "CH6", "HDMI"},
354         {"HDMI_CH0_MUX", "CH7", "HDMI"},          354         {"HDMI_CH0_MUX", "CH7", "HDMI"},
355                                                   355 
356         {"HDMI_CH1_MUX", "CH0", "HDMI"},          356         {"HDMI_CH1_MUX", "CH0", "HDMI"},
357         {"HDMI_CH1_MUX", "CH1", "HDMI"},          357         {"HDMI_CH1_MUX", "CH1", "HDMI"},
358         {"HDMI_CH1_MUX", "CH2", "HDMI"},          358         {"HDMI_CH1_MUX", "CH2", "HDMI"},
359         {"HDMI_CH1_MUX", "CH3", "HDMI"},          359         {"HDMI_CH1_MUX", "CH3", "HDMI"},
360         {"HDMI_CH1_MUX", "CH4", "HDMI"},          360         {"HDMI_CH1_MUX", "CH4", "HDMI"},
361         {"HDMI_CH1_MUX", "CH5", "HDMI"},          361         {"HDMI_CH1_MUX", "CH5", "HDMI"},
362         {"HDMI_CH1_MUX", "CH6", "HDMI"},          362         {"HDMI_CH1_MUX", "CH6", "HDMI"},
363         {"HDMI_CH1_MUX", "CH7", "HDMI"},          363         {"HDMI_CH1_MUX", "CH7", "HDMI"},
364                                                   364 
365         {"HDMI_CH2_MUX", "CH0", "HDMI"},          365         {"HDMI_CH2_MUX", "CH0", "HDMI"},
366         {"HDMI_CH2_MUX", "CH1", "HDMI"},          366         {"HDMI_CH2_MUX", "CH1", "HDMI"},
367         {"HDMI_CH2_MUX", "CH2", "HDMI"},          367         {"HDMI_CH2_MUX", "CH2", "HDMI"},
368         {"HDMI_CH2_MUX", "CH3", "HDMI"},          368         {"HDMI_CH2_MUX", "CH3", "HDMI"},
369         {"HDMI_CH2_MUX", "CH4", "HDMI"},          369         {"HDMI_CH2_MUX", "CH4", "HDMI"},
370         {"HDMI_CH2_MUX", "CH5", "HDMI"},          370         {"HDMI_CH2_MUX", "CH5", "HDMI"},
371         {"HDMI_CH2_MUX", "CH6", "HDMI"},          371         {"HDMI_CH2_MUX", "CH6", "HDMI"},
372         {"HDMI_CH2_MUX", "CH7", "HDMI"},          372         {"HDMI_CH2_MUX", "CH7", "HDMI"},
373                                                   373 
374         {"HDMI_CH3_MUX", "CH0", "HDMI"},          374         {"HDMI_CH3_MUX", "CH0", "HDMI"},
375         {"HDMI_CH3_MUX", "CH1", "HDMI"},          375         {"HDMI_CH3_MUX", "CH1", "HDMI"},
376         {"HDMI_CH3_MUX", "CH2", "HDMI"},          376         {"HDMI_CH3_MUX", "CH2", "HDMI"},
377         {"HDMI_CH3_MUX", "CH3", "HDMI"},          377         {"HDMI_CH3_MUX", "CH3", "HDMI"},
378         {"HDMI_CH3_MUX", "CH4", "HDMI"},          378         {"HDMI_CH3_MUX", "CH4", "HDMI"},
379         {"HDMI_CH3_MUX", "CH5", "HDMI"},          379         {"HDMI_CH3_MUX", "CH5", "HDMI"},
380         {"HDMI_CH3_MUX", "CH6", "HDMI"},          380         {"HDMI_CH3_MUX", "CH6", "HDMI"},
381         {"HDMI_CH3_MUX", "CH7", "HDMI"},          381         {"HDMI_CH3_MUX", "CH7", "HDMI"},
382                                                   382 
383         {"HDMI_CH4_MUX", "CH0", "HDMI"},          383         {"HDMI_CH4_MUX", "CH0", "HDMI"},
384         {"HDMI_CH4_MUX", "CH1", "HDMI"},          384         {"HDMI_CH4_MUX", "CH1", "HDMI"},
385         {"HDMI_CH4_MUX", "CH2", "HDMI"},          385         {"HDMI_CH4_MUX", "CH2", "HDMI"},
386         {"HDMI_CH4_MUX", "CH3", "HDMI"},          386         {"HDMI_CH4_MUX", "CH3", "HDMI"},
387         {"HDMI_CH4_MUX", "CH4", "HDMI"},          387         {"HDMI_CH4_MUX", "CH4", "HDMI"},
388         {"HDMI_CH4_MUX", "CH5", "HDMI"},          388         {"HDMI_CH4_MUX", "CH5", "HDMI"},
389         {"HDMI_CH4_MUX", "CH6", "HDMI"},          389         {"HDMI_CH4_MUX", "CH6", "HDMI"},
390         {"HDMI_CH4_MUX", "CH7", "HDMI"},          390         {"HDMI_CH4_MUX", "CH7", "HDMI"},
391                                                   391 
392         {"HDMI_CH5_MUX", "CH0", "HDMI"},          392         {"HDMI_CH5_MUX", "CH0", "HDMI"},
393         {"HDMI_CH5_MUX", "CH1", "HDMI"},          393         {"HDMI_CH5_MUX", "CH1", "HDMI"},
394         {"HDMI_CH5_MUX", "CH2", "HDMI"},          394         {"HDMI_CH5_MUX", "CH2", "HDMI"},
395         {"HDMI_CH5_MUX", "CH3", "HDMI"},          395         {"HDMI_CH5_MUX", "CH3", "HDMI"},
396         {"HDMI_CH5_MUX", "CH4", "HDMI"},          396         {"HDMI_CH5_MUX", "CH4", "HDMI"},
397         {"HDMI_CH5_MUX", "CH5", "HDMI"},          397         {"HDMI_CH5_MUX", "CH5", "HDMI"},
398         {"HDMI_CH5_MUX", "CH6", "HDMI"},          398         {"HDMI_CH5_MUX", "CH6", "HDMI"},
399         {"HDMI_CH5_MUX", "CH7", "HDMI"},          399         {"HDMI_CH5_MUX", "CH7", "HDMI"},
400                                                   400 
401         {"HDMI_CH6_MUX", "CH0", "HDMI"},          401         {"HDMI_CH6_MUX", "CH0", "HDMI"},
402         {"HDMI_CH6_MUX", "CH1", "HDMI"},          402         {"HDMI_CH6_MUX", "CH1", "HDMI"},
403         {"HDMI_CH6_MUX", "CH2", "HDMI"},          403         {"HDMI_CH6_MUX", "CH2", "HDMI"},
404         {"HDMI_CH6_MUX", "CH3", "HDMI"},          404         {"HDMI_CH6_MUX", "CH3", "HDMI"},
405         {"HDMI_CH6_MUX", "CH4", "HDMI"},          405         {"HDMI_CH6_MUX", "CH4", "HDMI"},
406         {"HDMI_CH6_MUX", "CH5", "HDMI"},          406         {"HDMI_CH6_MUX", "CH5", "HDMI"},
407         {"HDMI_CH6_MUX", "CH6", "HDMI"},          407         {"HDMI_CH6_MUX", "CH6", "HDMI"},
408         {"HDMI_CH6_MUX", "CH7", "HDMI"},          408         {"HDMI_CH6_MUX", "CH7", "HDMI"},
409                                                   409 
410         {"HDMI_CH7_MUX", "CH0", "HDMI"},          410         {"HDMI_CH7_MUX", "CH0", "HDMI"},
411         {"HDMI_CH7_MUX", "CH1", "HDMI"},          411         {"HDMI_CH7_MUX", "CH1", "HDMI"},
412         {"HDMI_CH7_MUX", "CH2", "HDMI"},          412         {"HDMI_CH7_MUX", "CH2", "HDMI"},
413         {"HDMI_CH7_MUX", "CH3", "HDMI"},          413         {"HDMI_CH7_MUX", "CH3", "HDMI"},
414         {"HDMI_CH7_MUX", "CH4", "HDMI"},          414         {"HDMI_CH7_MUX", "CH4", "HDMI"},
415         {"HDMI_CH7_MUX", "CH5", "HDMI"},          415         {"HDMI_CH7_MUX", "CH5", "HDMI"},
416         {"HDMI_CH7_MUX", "CH6", "HDMI"},          416         {"HDMI_CH7_MUX", "CH6", "HDMI"},
417         {"HDMI_CH7_MUX", "CH7", "HDMI"},          417         {"HDMI_CH7_MUX", "CH7", "HDMI"},
418                                                   418 
419         {"TDM", NULL, "HDMI_CH0_MUX"},            419         {"TDM", NULL, "HDMI_CH0_MUX"},
420         {"TDM", NULL, "HDMI_CH1_MUX"},            420         {"TDM", NULL, "HDMI_CH1_MUX"},
421         {"TDM", NULL, "HDMI_CH2_MUX"},            421         {"TDM", NULL, "HDMI_CH2_MUX"},
422         {"TDM", NULL, "HDMI_CH3_MUX"},            422         {"TDM", NULL, "HDMI_CH3_MUX"},
423         {"TDM", NULL, "HDMI_CH4_MUX"},            423         {"TDM", NULL, "HDMI_CH4_MUX"},
424         {"TDM", NULL, "HDMI_CH5_MUX"},            424         {"TDM", NULL, "HDMI_CH5_MUX"},
425         {"TDM", NULL, "HDMI_CH6_MUX"},            425         {"TDM", NULL, "HDMI_CH6_MUX"},
426         {"TDM", NULL, "HDMI_CH7_MUX"},            426         {"TDM", NULL, "HDMI_CH7_MUX"},
427                                                   427 
428         {"TDM", NULL, "aud_tdm_clk"},             428         {"TDM", NULL, "aud_tdm_clk"},
429         {"TDM", NULL, "TDM_BCK"},                 429         {"TDM", NULL, "TDM_BCK"},
430         {"TDM_BCK", NULL, "TDM_MCK"},             430         {"TDM_BCK", NULL, "TDM_MCK"},
431         {"TDM_MCK", NULL, APLL1_W_NAME, mtk_af    431         {"TDM_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect},
432         {"TDM_MCK", NULL, APLL2_W_NAME, mtk_af    432         {"TDM_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect},
433 };                                                433 };
434                                                   434 
435 /* dai ops */                                     435 /* dai ops */
436 static int mtk_dai_tdm_cal_mclk(struct mtk_bas    436 static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe,
437                                 struct mtk_afe    437                                 struct mtk_afe_tdm_priv *tdm_priv,
438                                 int freq)         438                                 int freq)
439 {                                                 439 {
440         int apll;                                 440         int apll;
441         int apll_rate;                            441         int apll_rate;
442                                                   442 
443         apll = mt8183_get_apll_by_rate(afe, fr    443         apll = mt8183_get_apll_by_rate(afe, freq);
444         apll_rate = mt8183_get_apll_rate(afe,     444         apll_rate = mt8183_get_apll_rate(afe, apll);
445                                                   445 
446         if (!freq || freq > apll_rate) {          446         if (!freq || freq > apll_rate) {
447                 dev_warn(afe->dev,                447                 dev_warn(afe->dev,
448                          "%s(), freq(%d Hz) in    448                          "%s(), freq(%d Hz) invalid\n", __func__, freq);
449                 return -EINVAL;                   449                 return -EINVAL;
450         }                                         450         }
451                                                   451 
452         if (apll_rate % freq != 0) {              452         if (apll_rate % freq != 0) {
453                 dev_warn(afe->dev,                453                 dev_warn(afe->dev,
454                          "%s(), APLL cannot ge    454                          "%s(), APLL cannot generate %d Hz", __func__, freq);
455                 return -EINVAL;                   455                 return -EINVAL;
456         }                                         456         }
457                                                   457 
458         tdm_priv->mclk_rate = freq;               458         tdm_priv->mclk_rate = freq;
459         tdm_priv->mclk_apll = apll;               459         tdm_priv->mclk_apll = apll;
460                                                   460 
461         return 0;                                 461         return 0;
462 }                                                 462 }
463                                                   463 
464 static int mtk_dai_tdm_hw_params(struct snd_pc    464 static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
465                                  struct snd_pc    465                                  struct snd_pcm_hw_params *params,
466                                  struct snd_so    466                                  struct snd_soc_dai *dai)
467 {                                                 467 {
468         struct mtk_base_afe *afe = snd_soc_dai    468         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
469         struct mt8183_afe_private *afe_priv =     469         struct mt8183_afe_private *afe_priv = afe->platform_priv;
470         int tdm_id = dai->id;                     470         int tdm_id = dai->id;
471         struct mtk_afe_tdm_priv *tdm_priv = af    471         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
472         unsigned int tdm_out_mode = tdm_priv->    472         unsigned int tdm_out_mode = tdm_priv->tdm_out_mode;
473         unsigned int rate = params_rate(params    473         unsigned int rate = params_rate(params);
474         unsigned int channels = params_channel    474         unsigned int channels = params_channels(params);
475         unsigned int out_channels_per_sdata =     475         unsigned int out_channels_per_sdata =
476                 get_tdm_ch_per_sdata(tdm_out_m    476                 get_tdm_ch_per_sdata(tdm_out_mode, channels);
477         snd_pcm_format_t format = params_forma    477         snd_pcm_format_t format = params_format(params);
478         unsigned int tdm_con = 0;                 478         unsigned int tdm_con = 0;
479                                                   479 
480         /* calculate mclk_rate, if not set exp    480         /* calculate mclk_rate, if not set explicitly */
481         if (!tdm_priv->mclk_rate) {               481         if (!tdm_priv->mclk_rate) {
482                 tdm_priv->mclk_rate = rate * t    482                 tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple;
483                 mtk_dai_tdm_cal_mclk(afe,         483                 mtk_dai_tdm_cal_mclk(afe,
484                                      tdm_priv,    484                                      tdm_priv,
485                                      tdm_priv-    485                                      tdm_priv->mclk_rate);
486         }                                         486         }
487                                                   487 
488         /* calculate bck */                       488         /* calculate bck */
489         tdm_priv->bck_rate = rate *               489         tdm_priv->bck_rate = rate *
490                              out_channels_per_    490                              out_channels_per_sdata *
491                              snd_pcm_format_ph    491                              snd_pcm_format_physical_width(format);
492                                                   492 
493         if (tdm_priv->bck_rate > tdm_priv->mcl    493         if (tdm_priv->bck_rate > tdm_priv->mclk_rate)
494                 dev_warn(afe->dev, "%s(), bck_    494                 dev_warn(afe->dev, "%s(), bck_rate > mclk_rate rate", __func__);
495                                                   495 
496         if (tdm_priv->mclk_rate % tdm_priv->bc    496         if (tdm_priv->mclk_rate % tdm_priv->bck_rate != 0)
497                 dev_warn(afe->dev, "%s(), bck     497                 dev_warn(afe->dev, "%s(), bck cannot generate", __func__);
498                                                   498 
499         dev_info(afe->dev, "%s(), id %d, rate     499         dev_info(afe->dev, "%s(), id %d, rate %d, channels %d, format %d, mclk_rate %d, bck_rate %d\n",
500                  __func__,                        500                  __func__,
501                  tdm_id, rate, channels, forma    501                  tdm_id, rate, channels, format,
502                  tdm_priv->mclk_rate, tdm_priv    502                  tdm_priv->mclk_rate, tdm_priv->bck_rate);
503         dev_info(afe->dev, "%s(), out_channels    503         dev_info(afe->dev, "%s(), out_channels_per_sdata = %d\n",
504                  __func__, out_channels_per_sd    504                  __func__, out_channels_per_sdata);
505                                                   505 
506         /* set tdm */                             506         /* set tdm */
507         if (tdm_priv->bck_invert)                 507         if (tdm_priv->bck_invert)
508                 regmap_update_bits(afe->regmap    508                 regmap_update_bits(afe->regmap, AUDIO_TOP_CON3,
509                                    BCK_INVERSE    509                                    BCK_INVERSE_MASK_SFT,
510                                    0x1 << BCK_    510                                    0x1 << BCK_INVERSE_SFT);
511                                                   511 
512         if (tdm_priv->lck_invert)                 512         if (tdm_priv->lck_invert)
513                 tdm_con |= 1 << LRCK_INVERSE_S    513                 tdm_con |= 1 << LRCK_INVERSE_SFT;
514                                                   514 
515         if (tdm_priv->tdm_out_mode == TDM_OUT_    515         if (tdm_priv->tdm_out_mode == TDM_OUT_I2S) {
516                 tdm_con |= 1 << DELAY_DATA_SFT    516                 tdm_con |= 1 << DELAY_DATA_SFT;
517                 tdm_con |= get_tdm_lrck_width(    517                 tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT;
518         } else if (tdm_priv->tdm_out_mode == T    518         } else if (tdm_priv->tdm_out_mode == TDM_OUT_TDM) {
519                 tdm_con |= 0 << DELAY_DATA_SFT    519                 tdm_con |= 0 << DELAY_DATA_SFT;
520                 tdm_con |= 0 << LRCK_TDM_WIDTH    520                 tdm_con |= 0 << LRCK_TDM_WIDTH_SFT;
521         }                                         521         }
522                                                   522 
523         tdm_con |= 1 << LEFT_ALIGN_SFT;           523         tdm_con |= 1 << LEFT_ALIGN_SFT;
524         tdm_con |= get_tdm_wlen(format) << WLE    524         tdm_con |= get_tdm_wlen(format) << WLEN_SFT;
525         tdm_con |= get_tdm_ch(out_channels_per    525         tdm_con |= get_tdm_ch(out_channels_per_sdata) << CHANNEL_NUM_SFT;
526         tdm_con |= get_tdm_channel_bck(format)    526         tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT;
527         regmap_write(afe->regmap, AFE_TDM_CON1    527         regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con);
528                                                   528 
529         if (out_channels_per_sdata == 2) {        529         if (out_channels_per_sdata == 2) {
530                 switch (channels) {               530                 switch (channels) {
531                 case 1:                           531                 case 1:
532                 case 2:                           532                 case 2:
533                         tdm_con = TDM_CH_START    533                         tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
534                         tdm_con |= TDM_CH_ZERO    534                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
535                         tdm_con |= TDM_CH_ZERO    535                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
536                         tdm_con |= TDM_CH_ZERO    536                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
537                         break;                    537                         break;
538                 case 3:                           538                 case 3:
539                 case 4:                           539                 case 4:
540                         tdm_con = TDM_CH_START    540                         tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
541                         tdm_con |= TDM_CH_STAR    541                         tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
542                         tdm_con |= TDM_CH_ZERO    542                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
543                         tdm_con |= TDM_CH_ZERO    543                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
544                         break;                    544                         break;
545                 case 5:                           545                 case 5:
546                 case 6:                           546                 case 6:
547                         tdm_con = TDM_CH_START    547                         tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
548                         tdm_con |= TDM_CH_STAR    548                         tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
549                         tdm_con |= TDM_CH_STAR    549                         tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
550                         tdm_con |= TDM_CH_ZERO    550                         tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
551                         break;                    551                         break;
552                 case 7:                           552                 case 7:
553                 case 8:                           553                 case 8:
554                         tdm_con = TDM_CH_START    554                         tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
555                         tdm_con |= TDM_CH_STAR    555                         tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT;
556                         tdm_con |= TDM_CH_STAR    556                         tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT;
557                         tdm_con |= TDM_CH_STAR    557                         tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT;
558                         break;                    558                         break;
559                 default:                          559                 default:
560                         tdm_con = 0;              560                         tdm_con = 0;
561                 }                                 561                 }
562         } else {                                  562         } else {
563                 tdm_con = TDM_CH_START_O30_O31    563                 tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT;
564                 tdm_con |= TDM_CH_ZERO << ST_C    564                 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT;
565                 tdm_con |= TDM_CH_ZERO << ST_C    565                 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT;
566                 tdm_con |= TDM_CH_ZERO << ST_C    566                 tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT;
567         }                                         567         }
568                                                   568 
569         regmap_write(afe->regmap, AFE_TDM_CON2    569         regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con);
570                                                   570 
571         regmap_update_bits(afe->regmap, AFE_HD    571         regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
572                            AFE_HDMI_OUT_CH_NUM    572                            AFE_HDMI_OUT_CH_NUM_MASK_SFT,
573                            channels << AFE_HDM    573                            channels << AFE_HDMI_OUT_CH_NUM_SFT);
574                                                   574 
575         regmap_update_bits(afe->regmap, AFE_HD    575         regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
576                            AFE_HDMI_OUT_BIT_WI    576                            AFE_HDMI_OUT_BIT_WIDTH_MASK_SFT,
577                            get_hdmi_wlen(forma    577                            get_hdmi_wlen(format) << AFE_HDMI_OUT_BIT_WIDTH_SFT);
578         return 0;                                 578         return 0;
579 }                                                 579 }
580                                                   580 
581 static int mtk_dai_tdm_trigger(struct snd_pcm_    581 static int mtk_dai_tdm_trigger(struct snd_pcm_substream *substream,
582                                int cmd,           582                                int cmd,
583                                struct snd_soc_    583                                struct snd_soc_dai *dai)
584 {                                                 584 {
585         struct mtk_base_afe *afe = snd_soc_dai    585         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
586                                                   586 
587         switch (cmd) {                            587         switch (cmd) {
588         case SNDRV_PCM_TRIGGER_START:             588         case SNDRV_PCM_TRIGGER_START:
589         case SNDRV_PCM_TRIGGER_RESUME:            589         case SNDRV_PCM_TRIGGER_RESUME:
590                 /* enable Out control */          590                 /* enable Out control */
591                 regmap_update_bits(afe->regmap    591                 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
592                                    AFE_HDMI_OU    592                                    AFE_HDMI_OUT_ON_MASK_SFT,
593                                    0x1 << AFE_    593                                    0x1 << AFE_HDMI_OUT_ON_SFT);
594                 /* enable tdm */                  594                 /* enable tdm */
595                 regmap_update_bits(afe->regmap    595                 regmap_update_bits(afe->regmap, AFE_TDM_CON1,
596                                    TDM_EN_MASK    596                                    TDM_EN_MASK_SFT, 0x1 << TDM_EN_SFT);
597                 break;                            597                 break;
598         case SNDRV_PCM_TRIGGER_STOP:              598         case SNDRV_PCM_TRIGGER_STOP:
599         case SNDRV_PCM_TRIGGER_SUSPEND:           599         case SNDRV_PCM_TRIGGER_SUSPEND:
600                 /* disable tdm */                 600                 /* disable tdm */
601                 regmap_update_bits(afe->regmap    601                 regmap_update_bits(afe->regmap, AFE_TDM_CON1,
602                                    TDM_EN_MASK    602                                    TDM_EN_MASK_SFT, 0);
603                 /* disable Out control */         603                 /* disable Out control */
604                 regmap_update_bits(afe->regmap    604                 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0,
605                                    AFE_HDMI_OU    605                                    AFE_HDMI_OUT_ON_MASK_SFT,
606                                    0);            606                                    0);
607                 break;                            607                 break;
608         default:                                  608         default:
609                 return -EINVAL;                   609                 return -EINVAL;
610         }                                         610         }
611                                                   611 
612         return 0;                                 612         return 0;
613 }                                                 613 }
614                                                   614 
615 static int mtk_dai_tdm_set_sysclk(struct snd_s    615 static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai,
616                                   int clk_id,     616                                   int clk_id, unsigned int freq, int dir)
617 {                                                 617 {
618         struct mtk_base_afe *afe = dev_get_drv    618         struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
619         struct mt8183_afe_private *afe_priv =     619         struct mt8183_afe_private *afe_priv = afe->platform_priv;
620         struct mtk_afe_tdm_priv *tdm_priv = af    620         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id];
621                                                   621 
622         if (!tdm_priv) {                          622         if (!tdm_priv) {
623                 dev_warn(afe->dev, "%s(), tdm_    623                 dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__);
624                 return -EINVAL;                   624                 return -EINVAL;
625         }                                         625         }
626                                                   626 
627         if (dir != SND_SOC_CLOCK_OUT) {           627         if (dir != SND_SOC_CLOCK_OUT) {
628                 dev_warn(afe->dev, "%s(), dir     628                 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
629                 return -EINVAL;                   629                 return -EINVAL;
630         }                                         630         }
631                                                   631 
632         dev_info(afe->dev, "%s(), freq %d\n",     632         dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
633                                                   633 
634         return mtk_dai_tdm_cal_mclk(afe, tdm_p    634         return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq);
635 }                                                 635 }
636                                                   636 
637 static int mtk_dai_tdm_set_fmt(struct snd_soc_    637 static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
638 {                                                 638 {
639         struct mtk_base_afe *afe = dev_get_drv    639         struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
640         struct mt8183_afe_private *afe_priv =     640         struct mt8183_afe_private *afe_priv = afe->platform_priv;
641         struct mtk_afe_tdm_priv *tdm_priv = af    641         struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id];
642                                                   642 
643         if (!tdm_priv) {                          643         if (!tdm_priv) {
644                 dev_warn(afe->dev, "%s(), tdm_    644                 dev_warn(afe->dev, "%s(), tdm_priv == NULL", __func__);
645                 return -EINVAL;                   645                 return -EINVAL;
646         }                                         646         }
647                                                   647 
648         /* DAI mode*/                             648         /* DAI mode*/
649         switch (fmt & SND_SOC_DAIFMT_FORMAT_MA    649         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
650         case SND_SOC_DAIFMT_I2S:                  650         case SND_SOC_DAIFMT_I2S:
651                 tdm_priv->tdm_out_mode = TDM_O    651                 tdm_priv->tdm_out_mode = TDM_OUT_I2S;
652                 break;                            652                 break;
653         case SND_SOC_DAIFMT_DSP_A:                653         case SND_SOC_DAIFMT_DSP_A:
654                 tdm_priv->tdm_out_mode = TDM_O    654                 tdm_priv->tdm_out_mode = TDM_OUT_TDM;
655                 break;                            655                 break;
656         default:                                  656         default:
657                 tdm_priv->tdm_out_mode = TDM_O    657                 tdm_priv->tdm_out_mode = TDM_OUT_I2S;
658         }                                         658         }
659                                                   659 
660         /* DAI clock inversion*/                  660         /* DAI clock inversion*/
661         switch (fmt & SND_SOC_DAIFMT_INV_MASK)    661         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
662         case SND_SOC_DAIFMT_NB_NF:                662         case SND_SOC_DAIFMT_NB_NF:
663                 tdm_priv->bck_invert = TDM_BCK    663                 tdm_priv->bck_invert = TDM_BCK_NON_INV;
664                 tdm_priv->lck_invert = TDM_LCK    664                 tdm_priv->lck_invert = TDM_LCK_NON_INV;
665                 break;                            665                 break;
666         case SND_SOC_DAIFMT_NB_IF:                666         case SND_SOC_DAIFMT_NB_IF:
667                 tdm_priv->bck_invert = TDM_BCK    667                 tdm_priv->bck_invert = TDM_BCK_NON_INV;
668                 tdm_priv->lck_invert = TDM_LCK    668                 tdm_priv->lck_invert = TDM_LCK_INV;
669                 break;                            669                 break;
670         case SND_SOC_DAIFMT_IB_NF:                670         case SND_SOC_DAIFMT_IB_NF:
671                 tdm_priv->bck_invert = TDM_BCK    671                 tdm_priv->bck_invert = TDM_BCK_INV;
672                 tdm_priv->lck_invert = TDM_LCK    672                 tdm_priv->lck_invert = TDM_LCK_NON_INV;
673                 break;                            673                 break;
674         case SND_SOC_DAIFMT_IB_IF:                674         case SND_SOC_DAIFMT_IB_IF:
675         default:                                  675         default:
676                 tdm_priv->bck_invert = TDM_BCK    676                 tdm_priv->bck_invert = TDM_BCK_INV;
677                 tdm_priv->lck_invert = TDM_LCK    677                 tdm_priv->lck_invert = TDM_LCK_INV;
678                 break;                            678                 break;
679         }                                         679         }
680                                                   680 
681         return 0;                                 681         return 0;
682 }                                                 682 }
683                                                   683 
684 static const struct snd_soc_dai_ops mtk_dai_td    684 static const struct snd_soc_dai_ops mtk_dai_tdm_ops = {
685         .hw_params = mtk_dai_tdm_hw_params,       685         .hw_params = mtk_dai_tdm_hw_params,
686         .trigger = mtk_dai_tdm_trigger,           686         .trigger = mtk_dai_tdm_trigger,
687         .set_sysclk = mtk_dai_tdm_set_sysclk,     687         .set_sysclk = mtk_dai_tdm_set_sysclk,
688         .set_fmt = mtk_dai_tdm_set_fmt,           688         .set_fmt = mtk_dai_tdm_set_fmt,
689 };                                                689 };
690                                                   690 
691 /* dai driver */                                  691 /* dai driver */
692 #define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_480    692 #define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\
693                        SNDRV_PCM_RATE_88200 |\    693                        SNDRV_PCM_RATE_88200 |\
694                        SNDRV_PCM_RATE_96000 |\    694                        SNDRV_PCM_RATE_96000 |\
695                        SNDRV_PCM_RATE_176400 |    695                        SNDRV_PCM_RATE_176400 |\
696                        SNDRV_PCM_RATE_192000)     696                        SNDRV_PCM_RATE_192000)
697                                                   697 
698 #define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_    698 #define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
699                          SNDRV_PCM_FMTBIT_S24_    699                          SNDRV_PCM_FMTBIT_S24_LE |\
700                          SNDRV_PCM_FMTBIT_S32_    700                          SNDRV_PCM_FMTBIT_S32_LE)
701                                                   701 
702 static struct snd_soc_dai_driver mtk_dai_tdm_d    702 static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = {
703         {                                         703         {
704                 .name = "TDM",                    704                 .name = "TDM",
705                 .id = MT8183_DAI_TDM,             705                 .id = MT8183_DAI_TDM,
706                 .playback = {                     706                 .playback = {
707                         .stream_name = "TDM",     707                         .stream_name = "TDM",
708                         .channels_min = 2,        708                         .channels_min = 2,
709                         .channels_max = 8,        709                         .channels_max = 8,
710                         .rates = MTK_TDM_RATES    710                         .rates = MTK_TDM_RATES,
711                         .formats = MTK_TDM_FOR    711                         .formats = MTK_TDM_FORMATS,
712                 },                                712                 },
713                 .ops = &mtk_dai_tdm_ops,          713                 .ops = &mtk_dai_tdm_ops,
714         },                                        714         },
715 };                                                715 };
716                                                   716 
717 int mt8183_dai_tdm_register(struct mtk_base_af    717 int mt8183_dai_tdm_register(struct mtk_base_afe *afe)
718 {                                                 718 {
719         struct mt8183_afe_private *afe_priv =     719         struct mt8183_afe_private *afe_priv = afe->platform_priv;
720         struct mtk_afe_tdm_priv *tdm_priv;        720         struct mtk_afe_tdm_priv *tdm_priv;
721         struct mtk_base_afe_dai *dai;             721         struct mtk_base_afe_dai *dai;
722                                                   722 
723         dai = devm_kzalloc(afe->dev, sizeof(*d    723         dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
724         if (!dai)                                 724         if (!dai)
725                 return -ENOMEM;                   725                 return -ENOMEM;
726                                                   726 
727         list_add(&dai->list, &afe->sub_dais);     727         list_add(&dai->list, &afe->sub_dais);
728                                                   728 
729         dai->dai_drivers = mtk_dai_tdm_driver;    729         dai->dai_drivers = mtk_dai_tdm_driver;
730         dai->num_dai_drivers = ARRAY_SIZE(mtk_    730         dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver);
731                                                   731 
732         dai->dapm_widgets = mtk_dai_tdm_widget    732         dai->dapm_widgets = mtk_dai_tdm_widgets;
733         dai->num_dapm_widgets = ARRAY_SIZE(mtk    733         dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets);
734         dai->dapm_routes = mtk_dai_tdm_routes;    734         dai->dapm_routes = mtk_dai_tdm_routes;
735         dai->num_dapm_routes = ARRAY_SIZE(mtk_    735         dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes);
736                                                   736 
737         tdm_priv = devm_kzalloc(afe->dev, size    737         tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv),
738                                 GFP_KERNEL);      738                                 GFP_KERNEL);
739         if (!tdm_priv)                            739         if (!tdm_priv)
740                 return -ENOMEM;                   740                 return -ENOMEM;
741                                                   741 
742         tdm_priv->mclk_multiple = 128;            742         tdm_priv->mclk_multiple = 128;
743         tdm_priv->bck_id = MT8183_I2S4_BCK;       743         tdm_priv->bck_id = MT8183_I2S4_BCK;
744         tdm_priv->mclk_id = MT8183_I2S4_MCK;      744         tdm_priv->mclk_id = MT8183_I2S4_MCK;
745                                                   745 
746         afe_priv->dai_priv[MT8183_DAI_TDM] = t    746         afe_priv->dai_priv[MT8183_DAI_TDM] = tdm_priv;
747         return 0;                                 747         return 0;
748 }                                                 748 }
749                                                   749 

~ [ 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