@@ -32,15 +32,16 @@ struct snd_soc_card_drvdata_davinci {
3232
3333static int evm_startup (struct snd_pcm_substream * substream )
3434{
35+ int ret = 0 ;
3536 struct snd_soc_pcm_runtime * rtd = substream -> private_data ;
3637 struct snd_soc_card * soc_card = rtd -> card ;
3738 struct snd_soc_card_drvdata_davinci * drvdata =
3839 snd_soc_card_get_drvdata (soc_card );
3940
4041 if (drvdata -> mclk )
41- return clk_prepare_enable (drvdata -> mclk );
42+ ret = clk_prepare_enable (drvdata -> mclk );
4243
43- return 0 ;
44+ return ret ;
4445}
4546
4647static void evm_shutdown (struct snd_pcm_substream * substream )
@@ -77,6 +78,81 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
7778
7879 return 0 ;
7980}
81+ static int wilink8_bt_hw_params (struct snd_pcm_substream * substream ,
82+ struct snd_pcm_hw_params * params )
83+ {
84+ struct snd_soc_pcm_runtime * rtd = substream -> private_data ;
85+ struct snd_soc_dai * cpu_dai = rtd -> cpu_dai ;
86+ struct snd_soc_codec * codec = rtd -> codec ;
87+ struct snd_soc_card * soc_card = rtd -> card ;
88+ struct platform_device * pdev = to_platform_device (soc_card -> dev );
89+ unsigned sysclk = ((struct snd_soc_card_drvdata_davinci * )
90+ snd_soc_card_get_drvdata (soc_card ))-> sysclk ;
91+ int ret = 0 ;
92+ int rate = params_rate (params );
93+
94+ if (rate == 16000 ) {
95+ /*
96+ * Works with tdm-slots set to 5 in the DT:
97+ * 5 slots each with a word-length of 20 gives us 100
98+ * bits/frame.
99+ */
100+ /* MCLK divider 24/3=8MHz */
101+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 0 , 3 );
102+ /* BCLK divider 8/5=1.6MHz */
103+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 1 , 5 );
104+ /* BCLK/FS ratio 1.6/100=16kHz FS */
105+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 2 , 100 );
106+
107+ /*
108+ * Works with tdm-slots set to 2 in the DT:
109+ * 2 slots each with a word-length of 30 gives us 60
110+ * bits/frame.
111+ *
112+ * ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 3);
113+ * ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, 5);
114+ * ret = snd_soc_dai_set_clkdiv(cpu_dai, 2, 100);
115+ */
116+ }
117+ else if (rate == 8000 ) {
118+ /*
119+ * Works with tdm-slots set to 5 in the DT:
120+ * 5 slots each with a word-length of 20 gives us 100
121+ * bits/frame.
122+ */
123+ /* MCLK divider 24/3=8MHz */
124+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 0 , 3 );
125+ /* BCLK divider 8/10=800kHz */
126+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 1 , 10 );
127+ /* BCLK/FS ratio 800/100=8kHz FS */
128+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 2 , 100 );
129+ }
130+ else if (rate == 48000 ) {
131+ /*
132+ * Works with tdm-slots set to 5 in the DT:
133+ * 5 slots each with a word-length of 20 gives us 100
134+ * bits/frame.
135+ */
136+ /* MCLK divider 24/1=24MHz */
137+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 0 , 1 );
138+ /* BCLK divider 24/5=4.8MHz */
139+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 1 , 5 );
140+ /* BCLK/FS ratio 4.8/100=48kHz FS */
141+ ret = snd_soc_dai_set_clkdiv (cpu_dai , 2 , 100 );
142+ } else {
143+ dev_err (& pdev -> dev , "Unsupported rate\n" );
144+ }
145+
146+ if (ret < 0 ) {
147+ dev_err (& pdev -> dev , "can't set CPU DAI clock divider %d\n" ,
148+ ret );
149+ return ret ;
150+ }
151+
152+ ret = snd_soc_dai_set_sysclk (cpu_dai , 0 , sysclk , SND_SOC_CLOCK_OUT );
153+
154+ return ret ;
155+ }
80156
81157/* If changing sample format the tda998x configuration (REG_CTS_N) needs
82158 to be changed. */
@@ -104,6 +180,11 @@ static struct snd_soc_ops evm_tda998x_ops = {
104180 .startup = evm_tda998x_startup ,
105181 .shutdown = evm_shutdown ,
106182};
183+ static struct snd_soc_ops wilink8_bt_ops = {
184+ .startup = evm_startup ,
185+ .shutdown = evm_shutdown ,
186+ .hw_params = wilink8_bt_hw_params ,
187+ };
107188
108189/* davinci-evm machine dapm widgets */
109190static const struct snd_soc_dapm_widget aic3x_dapm_widgets [] = {
@@ -407,6 +488,14 @@ static struct snd_soc_dai_link evm_dai_tda998x_hdmi = {
407488 .dai_fmt = (SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |
408489 SND_SOC_DAIFMT_IB_NF ),
409490};
491+ static struct snd_soc_dai_link evm_dai_wilink8_bt = {
492+ .name = "WILINK8_BT" ,
493+ .stream_name = "WILINK8" ,
494+ .codec_dai_name = "wilink8_bt-hifi" ,
495+ .ops = & wilink8_bt_ops ,
496+ .dai_fmt = (SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_NB_IF |
497+ SND_SOC_DAIFMT_DSP_A ),
498+ };
410499
411500static const struct of_device_id davinci_evm_dt_ids [] = {
412501 {
@@ -417,6 +506,10 @@ static const struct of_device_id davinci_evm_dt_ids[] = {
417506 .compatible = "ti,beaglebone-black-audio" ,
418507 .data = & evm_dai_tda998x_hdmi ,
419508 },
509+ {
510+ .compatible = "ti,wilink8-bt-audio" ,
511+ .data = & evm_dai_wilink8_bt ,
512+ },
420513 { /* sentinel */ }
421514};
422515MODULE_DEVICE_TABLE (of , davinci_evm_dt_ids );
0 commit comments