2424#define RIGHT_SPK_TDM_TX_MASK 0xC0
2525#define SPK_TDM_RX_MASK 0x03
2626#define NUM_TDM_SLOTS 8
27+ #define SLIM_MAX_TX_PORTS 16
28+ #define SLIM_MAX_RX_PORTS 16
29+ #define WCD934X_DEFAULT_MCLK_RATE 9600000
2730
2831struct sdm845_snd_data {
2932 struct snd_soc_jack jack ;
@@ -36,6 +39,39 @@ struct sdm845_snd_data {
3639
3740static unsigned int tdm_slot_offset [8 ] = {0 , 4 , 8 , 12 , 16 , 20 , 24 , 28 };
3841
42+ static int sdm845_slim_snd_hw_params (struct snd_pcm_substream * substream ,
43+ struct snd_pcm_hw_params * params )
44+ {
45+ struct snd_soc_pcm_runtime * rtd = substream -> private_data ;
46+ struct snd_soc_dai_link * dai_link = rtd -> dai_link ;
47+ struct snd_soc_dai * cpu_dai = rtd -> cpu_dai ;
48+ u32 rx_ch [SLIM_MAX_RX_PORTS ], tx_ch [SLIM_MAX_TX_PORTS ];
49+ u32 rx_ch_cnt = 0 , tx_ch_cnt = 0 ;
50+ int ret = 0 , i ;
51+
52+ for (i = 0 ; i < dai_link -> num_codecs ; i ++ ) {
53+ ret = snd_soc_dai_get_channel_map (rtd -> codec_dais [i ],
54+ & tx_ch_cnt , tx_ch , & rx_ch_cnt , rx_ch );
55+
56+ if (ret != 0 && ret != - ENOTSUPP ) {
57+ pr_err ("failed to get codec chan map, err:%d\n" , ret );
58+ return ret ;
59+ } else if (ret == - ENOTSUPP ) {
60+ /* Ignore unsupported */
61+ continue ;
62+ }
63+
64+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
65+ ret = snd_soc_dai_set_channel_map (cpu_dai , 0 , NULL ,
66+ rx_ch_cnt , rx_ch );
67+ else
68+ ret = snd_soc_dai_set_channel_map (cpu_dai , tx_ch_cnt ,
69+ tx_ch , 0 , NULL );
70+ }
71+
72+ return 0 ;
73+ }
74+
3975static int sdm845_tdm_snd_hw_params (struct snd_pcm_substream * substream ,
4076 struct snd_pcm_hw_params * params )
4177{
@@ -151,6 +187,11 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
151187 case QUATERNARY_TDM_TX_0 :
152188 ret = sdm845_tdm_snd_hw_params (substream , params );
153189 break ;
190+ case SLIMBUS_0_RX ...SLIMBUS_6_TX :
191+ ret = sdm845_slim_snd_hw_params (substream , params );
192+ break ;
193+ case QUATERNARY_MI2S_RX :
194+ break ;
154195 default :
155196 pr_err ("%s: invalid dai id 0x%x\n" , __func__ , cpu_dai -> id );
156197 break ;
@@ -173,7 +214,20 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
173214 struct snd_soc_dai * cpu_dai = rtd -> cpu_dai ;
174215 struct sdm845_snd_data * pdata = snd_soc_card_get_drvdata (card );
175216 struct snd_jack * jack ;
176- int rval ;
217+ struct snd_soc_dai_link * dai_link = rtd -> dai_link ;
218+ /*
219+ * Codec SLIMBUS configuration
220+ * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
221+ * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
222+ * TX14, TX15, TX16
223+ */
224+ unsigned int rx_ch [SLIM_MAX_RX_PORTS ] = {144 , 145 , 146 , 147 , 148 , 149 ,
225+ 150 , 151 , 152 , 153 , 154 , 155 , 156 };
226+ unsigned int tx_ch [SLIM_MAX_TX_PORTS ] = {128 , 129 , 130 , 131 , 132 , 133 ,
227+ 134 , 135 , 136 , 137 , 138 , 139 ,
228+ 140 , 141 , 142 , 143 };
229+ int rval , i ;
230+
177231
178232 if (!pdata -> jack_setup ) {
179233 rval = snd_soc_card_jack_new (card , "Headset Jack" ,
@@ -211,6 +265,21 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
211265 return rval ;
212266 }
213267 break ;
268+ case SLIMBUS_0_RX ...SLIMBUS_6_TX :
269+ for (i = 0 ; i < dai_link -> num_codecs ; i ++ ) {
270+ rval = snd_soc_dai_set_channel_map (rtd -> codec_dais [i ],
271+ ARRAY_SIZE (tx_ch ),
272+ tx_ch ,
273+ ARRAY_SIZE (rx_ch ),
274+ rx_ch );
275+ if (rval != 0 && rval != - ENOTSUPP )
276+ return rval ;
277+
278+ snd_soc_dai_set_sysclk (rtd -> codec_dais [i ], 0 ,
279+ WCD934X_DEFAULT_MCLK_RATE ,
280+ SNDRV_PCM_STREAM_PLAYBACK );
281+ }
282+ break ;
214283 default :
215284 break ;
216285 }
@@ -256,6 +325,14 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
256325 }
257326 snd_soc_dai_set_fmt (cpu_dai , fmt );
258327 snd_soc_dai_set_fmt (codec_dai , codec_dai_fmt );
328+ break ;
329+ case QUATERNARY_MI2S_RX :
330+ snd_soc_dai_set_sysclk (cpu_dai ,
331+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT ,
332+ MI2S_BCLK_RATE , SNDRV_PCM_STREAM_PLAYBACK );
333+ snd_soc_dai_set_fmt (cpu_dai , SND_SOC_DAIFMT_CBS_CFS );
334+
335+
259336 break ;
260337
261338 case QUATERNARY_TDM_RX_0 :
@@ -294,6 +371,8 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
294371 }
295372 }
296373 break ;
374+ case SLIMBUS_0_RX ...SLIMBUS_6_TX :
375+ break ;
297376
298377 default :
299378 pr_err ("%s: invalid dai id 0x%x\n" , __func__ , cpu_dai -> id );
@@ -338,6 +417,9 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
338417 0 , SNDRV_PCM_STREAM_PLAYBACK );
339418 }
340419 break ;
420+ case SLIMBUS_0_RX ...SLIMBUS_6_TX :
421+ case QUATERNARY_MI2S_RX :
422+ break ;
341423
342424 default :
343425 pr_err ("%s: invalid dai id 0x%x\n" , __func__ , cpu_dai -> id );
@@ -451,6 +533,8 @@ static int sdm845_snd_platform_remove(struct platform_device *pdev)
451533
452534static const struct of_device_id sdm845_snd_device_id [] = {
453535 { .compatible = "qcom,sdm845-sndcard" },
536+ { .compatible = "qcom,db845c-sndcard" },
537+ { .compatible = "lenovo,yoga-c630-sndcard" },
454538 {},
455539};
456540MODULE_DEVICE_TABLE (of , sdm845_snd_device_id );
0 commit comments