1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
6 #include <linux/module.h>
7 #include <linux/platform_device.h>
8 #include <linux/of_device.h>
9 #include <sound/core.h>
10 #include <sound/pcm.h>
11 #include <sound/pcm_params.h>
12 #include <sound/jack.h>
13 #include <sound/soc.h>
14 #include <uapi/linux/input-event-codes.h>
16 #include "qdsp6/q6afe.h"
17 #include "../codecs/rt5663.h"
19 #define DEFAULT_SAMPLE_RATE_48K 48000
20 #define DEFAULT_MCLK_RATE 24576000
21 #define TDM_BCLK_RATE 6144000
22 #define MI2S_BCLK_RATE 1536000
23 #define LEFT_SPK_TDM_TX_MASK 0x30
24 #define RIGHT_SPK_TDM_TX_MASK 0xC0
25 #define SPK_TDM_RX_MASK 0x03
26 #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
31 struct sdm845_snd_data
{
32 struct snd_soc_jack jack
;
34 struct snd_soc_card
*card
;
35 uint32_t pri_mi2s_clk_count
;
36 uint32_t sec_mi2s_clk_count
;
37 uint32_t quat_tdm_clk_count
;
40 static unsigned int tdm_slot_offset
[8] = {0, 4, 8, 12, 16, 20, 24, 28};
42 static int sdm845_slim_snd_hw_params(struct snd_pcm_substream
*substream
,
43 struct snd_pcm_hw_params
*params
)
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;
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
);
56 if (ret
!= 0 && ret
!= -ENOTSUPP
) {
57 pr_err("failed to get codec chan map, err:%d\n", ret
);
59 } else if (ret
== -ENOTSUPP
) {
60 /* Ignore unsupported */
64 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
65 ret
= snd_soc_dai_set_channel_map(cpu_dai
, 0, NULL
,
68 ret
= snd_soc_dai_set_channel_map(cpu_dai
, tx_ch_cnt
,
75 static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream
*substream
,
76 struct snd_pcm_hw_params
*params
)
78 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
79 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
81 int channels
, slot_width
;
83 switch (params_format(params
)) {
84 case SNDRV_PCM_FORMAT_S16_LE
:
88 dev_err(rtd
->dev
, "%s: invalid param format 0x%x\n",
89 __func__
, params_format(params
));
93 channels
= params_channels(params
);
94 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
95 ret
= snd_soc_dai_set_tdm_slot(cpu_dai
, 0, 0x3,
98 dev_err(rtd
->dev
, "%s: failed to set tdm slot, err:%d\n",
103 ret
= snd_soc_dai_set_channel_map(cpu_dai
, 0, NULL
,
104 channels
, tdm_slot_offset
);
106 dev_err(rtd
->dev
, "%s: failed to set channel map, err:%d\n",
111 ret
= snd_soc_dai_set_tdm_slot(cpu_dai
, 0xf, 0,
114 dev_err(rtd
->dev
, "%s: failed to set tdm slot, err:%d\n",
119 ret
= snd_soc_dai_set_channel_map(cpu_dai
, channels
,
120 tdm_slot_offset
, 0, NULL
);
122 dev_err(rtd
->dev
, "%s: failed to set channel map, err:%d\n",
128 for (j
= 0; j
< rtd
->num_codecs
; j
++) {
129 struct snd_soc_dai
*codec_dai
= rtd
->codec_dais
[j
];
131 if (!strcmp(codec_dai
->component
->name_prefix
, "Left")) {
132 ret
= snd_soc_dai_set_tdm_slot(
133 codec_dai
, LEFT_SPK_TDM_TX_MASK
,
134 SPK_TDM_RX_MASK
, NUM_TDM_SLOTS
,
138 "DEV0 TDM slot err:%d\n", ret
);
143 if (!strcmp(codec_dai
->component
->name_prefix
, "Right")) {
144 ret
= snd_soc_dai_set_tdm_slot(
145 codec_dai
, RIGHT_SPK_TDM_TX_MASK
,
146 SPK_TDM_RX_MASK
, NUM_TDM_SLOTS
,
150 "DEV1 TDM slot err:%d\n", ret
);
160 static int sdm845_snd_hw_params(struct snd_pcm_substream
*substream
,
161 struct snd_pcm_hw_params
*params
)
163 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
164 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
165 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
168 switch (cpu_dai
->id
) {
169 case PRIMARY_MI2S_RX
:
170 case PRIMARY_MI2S_TX
:
172 * Use ASRC for internal clocks, as PLL rate isn't multiple
175 rt5663_sel_asrc_clk_src(
176 codec_dai
->component
,
177 RT5663_DA_STEREO_FILTER
| RT5663_AD_STEREO_FILTER
,
178 RT5663_CLK_SEL_I2S1_ASRC
);
179 ret
= snd_soc_dai_set_sysclk(
180 codec_dai
, RT5663_SCLK_S_MCLK
, DEFAULT_MCLK_RATE
,
184 "snd_soc_dai_set_sysclk err = %d\n", ret
);
186 case QUATERNARY_TDM_RX_0
:
187 case QUATERNARY_TDM_TX_0
:
188 ret
= sdm845_tdm_snd_hw_params(substream
, params
);
190 case SLIMBUS_0_RX
...SLIMBUS_6_TX
:
191 ret
= sdm845_slim_snd_hw_params(substream
, params
);
193 case QUATERNARY_MI2S_RX
:
196 pr_err("%s: invalid dai id 0x%x\n", __func__
, cpu_dai
->id
);
202 static void sdm845_jack_free(struct snd_jack
*jack
)
204 struct snd_soc_component
*component
= jack
->private_data
;
206 snd_soc_component_set_jack(component
, NULL
, NULL
);
209 static int sdm845_dai_init(struct snd_soc_pcm_runtime
*rtd
)
211 struct snd_soc_component
*component
;
212 struct snd_soc_card
*card
= rtd
->card
;
213 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
214 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
215 struct sdm845_snd_data
*pdata
= snd_soc_card_get_drvdata(card
);
216 struct snd_jack
*jack
;
217 struct snd_soc_dai_link
*dai_link
= rtd
->dai_link
;
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
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,
232 if (!pdata
->jack_setup
) {
233 rval
= snd_soc_card_jack_new(card
, "Headset Jack",
236 SND_JACK_BTN_0
| SND_JACK_BTN_1
|
237 SND_JACK_BTN_2
| SND_JACK_BTN_3
,
238 &pdata
->jack
, NULL
, 0);
241 dev_err(card
->dev
, "Unable to add Headphone Jack\n");
245 jack
= pdata
->jack
.jack
;
247 snd_jack_set_key(jack
, SND_JACK_BTN_0
, KEY_PLAYPAUSE
);
248 snd_jack_set_key(jack
, SND_JACK_BTN_1
, KEY_VOICECOMMAND
);
249 snd_jack_set_key(jack
, SND_JACK_BTN_2
, KEY_VOLUMEUP
);
250 snd_jack_set_key(jack
, SND_JACK_BTN_3
, KEY_VOLUMEDOWN
);
251 pdata
->jack_setup
= true;
254 switch (cpu_dai
->id
) {
255 case PRIMARY_MI2S_RX
:
256 jack
= pdata
->jack
.jack
;
257 component
= codec_dai
->component
;
259 jack
->private_data
= component
;
260 jack
->private_free
= sdm845_jack_free
;
261 rval
= snd_soc_component_set_jack(component
,
263 if (rval
!= 0 && rval
!= -ENOTSUPP
) {
264 dev_warn(card
->dev
, "Failed to set jack: %d\n", rval
);
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
],
275 if (rval
!= 0 && rval
!= -ENOTSUPP
)
278 snd_soc_dai_set_sysclk(rtd
->codec_dais
[i
], 0,
279 WCD934X_DEFAULT_MCLK_RATE
,
280 SNDRV_PCM_STREAM_PLAYBACK
);
291 static int sdm845_snd_startup(struct snd_pcm_substream
*substream
)
293 unsigned int fmt
= SND_SOC_DAIFMT_CBS_CFS
;
294 unsigned int codec_dai_fmt
= SND_SOC_DAIFMT_CBS_CFS
;
295 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
296 struct snd_soc_card
*card
= rtd
->card
;
297 struct sdm845_snd_data
*data
= snd_soc_card_get_drvdata(card
);
298 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
299 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
303 switch (cpu_dai
->id
) {
304 case PRIMARY_MI2S_RX
:
305 case PRIMARY_MI2S_TX
:
306 codec_dai_fmt
|= SND_SOC_DAIFMT_NB_NF
;
307 if (++(data
->pri_mi2s_clk_count
) == 1) {
308 snd_soc_dai_set_sysclk(cpu_dai
,
309 Q6AFE_LPASS_CLK_ID_MCLK_1
,
310 DEFAULT_MCLK_RATE
, SNDRV_PCM_STREAM_PLAYBACK
);
311 snd_soc_dai_set_sysclk(cpu_dai
,
312 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT
,
313 MI2S_BCLK_RATE
, SNDRV_PCM_STREAM_PLAYBACK
);
315 snd_soc_dai_set_fmt(cpu_dai
, fmt
);
316 snd_soc_dai_set_fmt(codec_dai
, codec_dai_fmt
);
319 case SECONDARY_MI2S_TX
:
320 codec_dai_fmt
|= SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_I2S
;
321 if (++(data
->sec_mi2s_clk_count
) == 1) {
322 snd_soc_dai_set_sysclk(cpu_dai
,
323 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT
,
324 MI2S_BCLK_RATE
, SNDRV_PCM_STREAM_CAPTURE
);
326 snd_soc_dai_set_fmt(cpu_dai
, fmt
);
327 snd_soc_dai_set_fmt(codec_dai
, codec_dai_fmt
);
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
);
338 case QUATERNARY_TDM_RX_0
:
339 case QUATERNARY_TDM_TX_0
:
340 if (++(data
->quat_tdm_clk_count
) == 1) {
341 snd_soc_dai_set_sysclk(cpu_dai
,
342 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT
,
343 TDM_BCLK_RATE
, SNDRV_PCM_STREAM_PLAYBACK
);
346 codec_dai_fmt
|= SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_DSP_B
;
348 for (j
= 0; j
< rtd
->num_codecs
; j
++) {
349 codec_dai
= rtd
->codec_dais
[j
];
351 if (!strcmp(codec_dai
->component
->name_prefix
,
353 ret
= snd_soc_dai_set_fmt(
354 codec_dai
, codec_dai_fmt
);
357 "Left TDM fmt err:%d\n", ret
);
362 if (!strcmp(codec_dai
->component
->name_prefix
,
364 ret
= snd_soc_dai_set_fmt(
365 codec_dai
, codec_dai_fmt
);
368 "Right TDM slot err:%d\n", ret
);
374 case SLIMBUS_0_RX
...SLIMBUS_6_TX
:
378 pr_err("%s: invalid dai id 0x%x\n", __func__
, cpu_dai
->id
);
384 static void sdm845_snd_shutdown(struct snd_pcm_substream
*substream
)
386 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
387 struct snd_soc_card
*card
= rtd
->card
;
388 struct sdm845_snd_data
*data
= snd_soc_card_get_drvdata(card
);
389 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
391 switch (cpu_dai
->id
) {
392 case PRIMARY_MI2S_RX
:
393 case PRIMARY_MI2S_TX
:
394 if (--(data
->pri_mi2s_clk_count
) == 0) {
395 snd_soc_dai_set_sysclk(cpu_dai
,
396 Q6AFE_LPASS_CLK_ID_MCLK_1
,
397 0, SNDRV_PCM_STREAM_PLAYBACK
);
398 snd_soc_dai_set_sysclk(cpu_dai
,
399 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT
,
400 0, SNDRV_PCM_STREAM_PLAYBACK
);
404 case SECONDARY_MI2S_TX
:
405 if (--(data
->sec_mi2s_clk_count
) == 0) {
406 snd_soc_dai_set_sysclk(cpu_dai
,
407 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT
,
408 0, SNDRV_PCM_STREAM_CAPTURE
);
412 case QUATERNARY_TDM_RX_0
:
413 case QUATERNARY_TDM_TX_0
:
414 if (--(data
->quat_tdm_clk_count
) == 0) {
415 snd_soc_dai_set_sysclk(cpu_dai
,
416 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT
,
417 0, SNDRV_PCM_STREAM_PLAYBACK
);
420 case SLIMBUS_0_RX
...SLIMBUS_6_TX
:
421 case QUATERNARY_MI2S_RX
:
425 pr_err("%s: invalid dai id 0x%x\n", __func__
, cpu_dai
->id
);
430 static const struct snd_soc_ops sdm845_be_ops
= {
431 .hw_params
= sdm845_snd_hw_params
,
432 .startup
= sdm845_snd_startup
,
433 .shutdown
= sdm845_snd_shutdown
,
436 static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime
*rtd
,
437 struct snd_pcm_hw_params
*params
)
439 struct snd_interval
*rate
= hw_param_interval(params
,
440 SNDRV_PCM_HW_PARAM_RATE
);
441 struct snd_interval
*channels
= hw_param_interval(params
,
442 SNDRV_PCM_HW_PARAM_CHANNELS
);
443 struct snd_mask
*fmt
= hw_param_mask(params
, SNDRV_PCM_HW_PARAM_FORMAT
);
445 rate
->min
= rate
->max
= DEFAULT_SAMPLE_RATE_48K
;
446 channels
->min
= channels
->max
= 2;
447 snd_mask_set_format(fmt
, SNDRV_PCM_FORMAT_S16_LE
);
452 static const struct snd_soc_dapm_widget sdm845_snd_widgets
[] = {
453 SND_SOC_DAPM_HP("Headphone Jack", NULL
),
454 SND_SOC_DAPM_MIC("Headset Mic", NULL
),
455 SND_SOC_DAPM_SPK("Left Spk", NULL
),
456 SND_SOC_DAPM_SPK("Right Spk", NULL
),
457 SND_SOC_DAPM_MIC("Int Mic", NULL
),
460 static void sdm845_add_ops(struct snd_soc_card
*card
)
462 struct snd_soc_dai_link
*link
;
465 for_each_card_prelinks(card
, i
, link
) {
466 if (link
->no_pcm
== 1) {
467 link
->ops
= &sdm845_be_ops
;
468 link
->be_hw_params_fixup
= sdm845_be_hw_params_fixup
;
470 link
->init
= sdm845_dai_init
;
474 static int sdm845_snd_platform_probe(struct platform_device
*pdev
)
476 struct snd_soc_card
*card
;
477 struct sdm845_snd_data
*data
;
478 struct device
*dev
= &pdev
->dev
;
481 card
= kzalloc(sizeof(*card
), GFP_KERNEL
);
485 /* Allocate the private data */
486 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
489 goto data_alloc_fail
;
492 card
->dapm_widgets
= sdm845_snd_widgets
;
493 card
->num_dapm_widgets
= ARRAY_SIZE(sdm845_snd_widgets
);
495 dev_set_drvdata(dev
, card
);
496 ret
= qcom_snd_parse_of(card
);
498 dev_err(dev
, "Error parsing OF data\n");
503 snd_soc_card_set_drvdata(card
, data
);
505 sdm845_add_ops(card
);
506 ret
= snd_soc_register_card(card
);
508 dev_err(dev
, "Sound card registration failed\n");
509 goto register_card_fail
;
514 kfree(card
->dai_link
);
522 static int sdm845_snd_platform_remove(struct platform_device
*pdev
)
524 struct snd_soc_card
*card
= dev_get_drvdata(&pdev
->dev
);
525 struct sdm845_snd_data
*data
= snd_soc_card_get_drvdata(card
);
527 snd_soc_unregister_card(card
);
528 kfree(card
->dai_link
);
534 static const struct of_device_id sdm845_snd_device_id
[] = {
535 { .compatible
= "qcom,sdm845-sndcard" },
536 { .compatible
= "qcom,db845c-sndcard" },
537 { .compatible
= "lenovo,yoga-c630-sndcard" },
540 MODULE_DEVICE_TABLE(of
, sdm845_snd_device_id
);
542 static struct platform_driver sdm845_snd_driver
= {
543 .probe
= sdm845_snd_platform_probe
,
544 .remove
= sdm845_snd_platform_remove
,
546 .name
= "msm-snd-sdm845",
547 .of_match_table
= sdm845_snd_device_id
,
550 module_platform_driver(sdm845_snd_driver
);
552 MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
553 MODULE_LICENSE("GPL v2");