1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 */ 5 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> 15 #include "common.h" 16 #include "qdsp6/q6afe.h" 17 #include "../codecs/rt5663.h" 18 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 28 struct sdm845_snd_data { 29 struct snd_soc_jack jack; 30 bool jack_setup; 31 struct snd_soc_card *card; 32 uint32_t pri_mi2s_clk_count; 33 uint32_t sec_mi2s_clk_count; 34 uint32_t quat_tdm_clk_count; 35 }; 36 37 static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; 38 39 static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, 40 struct snd_pcm_hw_params *params) 41 { 42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 44 int ret = 0, j; 45 int channels, slot_width; 46 47 switch (params_format(params)) { 48 case SNDRV_PCM_FORMAT_S16_LE: 49 slot_width = 16; 50 break; 51 default: 52 dev_err(rtd->dev, "%s: invalid param format 0x%x\n", 53 __func__, params_format(params)); 54 return -EINVAL; 55 } 56 57 channels = params_channels(params); 58 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 59 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3, 60 8, slot_width); 61 if (ret < 0) { 62 dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n", 63 __func__, ret); 64 goto end; 65 } 66 67 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, 68 channels, tdm_slot_offset); 69 if (ret < 0) { 70 dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n", 71 __func__, ret); 72 goto end; 73 } 74 } else { 75 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0, 76 8, slot_width); 77 if (ret < 0) { 78 dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n", 79 __func__, ret); 80 goto end; 81 } 82 83 ret = snd_soc_dai_set_channel_map(cpu_dai, channels, 84 tdm_slot_offset, 0, NULL); 85 if (ret < 0) { 86 dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n", 87 __func__, ret); 88 goto end; 89 } 90 } 91 92 for (j = 0; j < rtd->num_codecs; j++) { 93 struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 94 95 if (!strcmp(codec_dai->component->name_prefix, "Left")) { 96 ret = snd_soc_dai_set_tdm_slot( 97 codec_dai, LEFT_SPK_TDM_TX_MASK, 98 SPK_TDM_RX_MASK, NUM_TDM_SLOTS, 99 slot_width); 100 if (ret < 0) { 101 dev_err(rtd->dev, 102 "DEV0 TDM slot err:%d\n", ret); 103 return ret; 104 } 105 } 106 107 if (!strcmp(codec_dai->component->name_prefix, "Right")) { 108 ret = snd_soc_dai_set_tdm_slot( 109 codec_dai, RIGHT_SPK_TDM_TX_MASK, 110 SPK_TDM_RX_MASK, NUM_TDM_SLOTS, 111 slot_width); 112 if (ret < 0) { 113 dev_err(rtd->dev, 114 "DEV1 TDM slot err:%d\n", ret); 115 return ret; 116 } 117 } 118 } 119 120 end: 121 return ret; 122 } 123 124 static int sdm845_snd_hw_params(struct snd_pcm_substream *substream, 125 struct snd_pcm_hw_params *params) 126 { 127 struct snd_soc_pcm_runtime *rtd = substream->private_data; 128 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 129 struct snd_soc_dai *codec_dai = rtd->codec_dai; 130 int ret = 0; 131 132 switch (cpu_dai->id) { 133 case PRIMARY_MI2S_RX: 134 case PRIMARY_MI2S_TX: 135 /* 136 * Use ASRC for internal clocks, as PLL rate isn't multiple 137 * of BCLK. 138 */ 139 rt5663_sel_asrc_clk_src( 140 codec_dai->component, 141 RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, 142 RT5663_CLK_SEL_I2S1_ASRC); 143 ret = snd_soc_dai_set_sysclk( 144 codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE, 145 SND_SOC_CLOCK_IN); 146 if (ret < 0) 147 dev_err(rtd->dev, 148 "snd_soc_dai_set_sysclk err = %d\n", ret); 149 break; 150 case QUATERNARY_TDM_RX_0: 151 case QUATERNARY_TDM_TX_0: 152 ret = sdm845_tdm_snd_hw_params(substream, params); 153 break; 154 default: 155 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); 156 break; 157 } 158 return ret; 159 } 160 161 static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd) 162 { 163 struct snd_soc_component *component; 164 struct snd_soc_dai_link *dai_link = rtd->dai_link; 165 struct snd_soc_card *card = rtd->card; 166 struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card); 167 int i, rval; 168 169 if (!pdata->jack_setup) { 170 struct snd_jack *jack; 171 172 rval = snd_soc_card_jack_new(card, "Headset Jack", 173 SND_JACK_HEADSET | 174 SND_JACK_HEADPHONE | 175 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 176 SND_JACK_BTN_2 | SND_JACK_BTN_3, 177 &pdata->jack, NULL, 0); 178 179 if (rval < 0) { 180 dev_err(card->dev, "Unable to add Headphone Jack\n"); 181 return rval; 182 } 183 184 jack = pdata->jack.jack; 185 186 snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 187 snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 188 snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 189 snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 190 pdata->jack_setup = true; 191 } 192 193 for (i = 0 ; i < dai_link->num_codecs; i++) { 194 struct snd_soc_dai *dai = rtd->codec_dais[i]; 195 196 component = dai->component; 197 rval = snd_soc_component_set_jack( 198 component, &pdata->jack, NULL); 199 if (rval != 0 && rval != -ENOTSUPP) { 200 dev_warn(card->dev, "Failed to set jack: %d\n", rval); 201 return rval; 202 } 203 } 204 205 return 0; 206 } 207 208 209 static int sdm845_snd_startup(struct snd_pcm_substream *substream) 210 { 211 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; 212 unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; 213 struct snd_soc_pcm_runtime *rtd = substream->private_data; 214 struct snd_soc_card *card = rtd->card; 215 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 216 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 217 struct snd_soc_dai *codec_dai = rtd->codec_dai; 218 int j; 219 int ret; 220 221 switch (cpu_dai->id) { 222 case PRIMARY_MI2S_RX: 223 case PRIMARY_MI2S_TX: 224 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF; 225 if (++(data->pri_mi2s_clk_count) == 1) { 226 snd_soc_dai_set_sysclk(cpu_dai, 227 Q6AFE_LPASS_CLK_ID_MCLK_1, 228 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 229 snd_soc_dai_set_sysclk(cpu_dai, 230 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, 231 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 232 } 233 snd_soc_dai_set_fmt(cpu_dai, fmt); 234 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); 235 break; 236 237 case SECONDARY_MI2S_TX: 238 if (++(data->sec_mi2s_clk_count) == 1) { 239 snd_soc_dai_set_sysclk(cpu_dai, 240 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, 241 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE); 242 } 243 snd_soc_dai_set_fmt(cpu_dai, fmt); 244 break; 245 246 case QUATERNARY_TDM_RX_0: 247 case QUATERNARY_TDM_TX_0: 248 if (++(data->quat_tdm_clk_count) == 1) { 249 snd_soc_dai_set_sysclk(cpu_dai, 250 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, 251 TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 252 } 253 254 codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B; 255 256 for (j = 0; j < rtd->num_codecs; j++) { 257 codec_dai = rtd->codec_dais[j]; 258 259 if (!strcmp(codec_dai->component->name_prefix, 260 "Left")) { 261 ret = snd_soc_dai_set_fmt( 262 codec_dai, codec_dai_fmt); 263 if (ret < 0) { 264 dev_err(rtd->dev, 265 "Left TDM fmt err:%d\n", ret); 266 return ret; 267 } 268 } 269 270 if (!strcmp(codec_dai->component->name_prefix, 271 "Right")) { 272 ret = snd_soc_dai_set_fmt( 273 codec_dai, codec_dai_fmt); 274 if (ret < 0) { 275 dev_err(rtd->dev, 276 "Right TDM slot err:%d\n", ret); 277 return ret; 278 } 279 } 280 } 281 break; 282 283 default: 284 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); 285 break; 286 } 287 return 0; 288 } 289 290 static void sdm845_snd_shutdown(struct snd_pcm_substream *substream) 291 { 292 struct snd_soc_pcm_runtime *rtd = substream->private_data; 293 struct snd_soc_card *card = rtd->card; 294 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 295 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 296 297 switch (cpu_dai->id) { 298 case PRIMARY_MI2S_RX: 299 case PRIMARY_MI2S_TX: 300 if (--(data->pri_mi2s_clk_count) == 0) { 301 snd_soc_dai_set_sysclk(cpu_dai, 302 Q6AFE_LPASS_CLK_ID_MCLK_1, 303 0, SNDRV_PCM_STREAM_PLAYBACK); 304 snd_soc_dai_set_sysclk(cpu_dai, 305 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, 306 0, SNDRV_PCM_STREAM_PLAYBACK); 307 }; 308 break; 309 310 case SECONDARY_MI2S_TX: 311 if (--(data->sec_mi2s_clk_count) == 0) { 312 snd_soc_dai_set_sysclk(cpu_dai, 313 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, 314 0, SNDRV_PCM_STREAM_CAPTURE); 315 } 316 break; 317 318 case QUATERNARY_TDM_RX_0: 319 case QUATERNARY_TDM_TX_0: 320 if (--(data->quat_tdm_clk_count) == 0) { 321 snd_soc_dai_set_sysclk(cpu_dai, 322 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, 323 0, SNDRV_PCM_STREAM_PLAYBACK); 324 } 325 break; 326 327 default: 328 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); 329 break; 330 } 331 } 332 333 static const struct snd_soc_ops sdm845_be_ops = { 334 .hw_params = sdm845_snd_hw_params, 335 .startup = sdm845_snd_startup, 336 .shutdown = sdm845_snd_shutdown, 337 }; 338 339 static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 340 struct snd_pcm_hw_params *params) 341 { 342 struct snd_interval *rate = hw_param_interval(params, 343 SNDRV_PCM_HW_PARAM_RATE); 344 struct snd_interval *channels = hw_param_interval(params, 345 SNDRV_PCM_HW_PARAM_CHANNELS); 346 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 347 348 rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K; 349 channels->min = channels->max = 2; 350 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); 351 352 return 0; 353 } 354 355 static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = { 356 SND_SOC_DAPM_HP("Headphone Jack", NULL), 357 SND_SOC_DAPM_MIC("Headset Mic", NULL), 358 SND_SOC_DAPM_SPK("Left Spk", NULL), 359 SND_SOC_DAPM_SPK("Right Spk", NULL), 360 SND_SOC_DAPM_MIC("Int Mic", NULL), 361 }; 362 363 static void sdm845_add_ops(struct snd_soc_card *card) 364 { 365 struct snd_soc_dai_link *link; 366 int i; 367 368 for_each_card_prelinks(card, i, link) { 369 if (link->no_pcm == 1) { 370 link->ops = &sdm845_be_ops; 371 link->be_hw_params_fixup = sdm845_be_hw_params_fixup; 372 } 373 link->init = sdm845_dai_init; 374 } 375 } 376 377 static int sdm845_snd_platform_probe(struct platform_device *pdev) 378 { 379 struct snd_soc_card *card; 380 struct sdm845_snd_data *data; 381 struct device *dev = &pdev->dev; 382 int ret; 383 384 card = kzalloc(sizeof(*card), GFP_KERNEL); 385 if (!card) 386 return -ENOMEM; 387 388 /* Allocate the private data */ 389 data = kzalloc(sizeof(*data), GFP_KERNEL); 390 if (!data) { 391 ret = -ENOMEM; 392 goto data_alloc_fail; 393 } 394 395 card->dapm_widgets = sdm845_snd_widgets; 396 card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets); 397 card->dev = dev; 398 dev_set_drvdata(dev, card); 399 ret = qcom_snd_parse_of(card); 400 if (ret) { 401 dev_err(dev, "Error parsing OF data\n"); 402 goto parse_dt_fail; 403 } 404 405 data->card = card; 406 snd_soc_card_set_drvdata(card, data); 407 408 sdm845_add_ops(card); 409 ret = snd_soc_register_card(card); 410 if (ret) { 411 dev_err(dev, "Sound card registration failed\n"); 412 goto register_card_fail; 413 } 414 return ret; 415 416 register_card_fail: 417 kfree(card->dai_link); 418 parse_dt_fail: 419 kfree(data); 420 data_alloc_fail: 421 kfree(card); 422 return ret; 423 } 424 425 static int sdm845_snd_platform_remove(struct platform_device *pdev) 426 { 427 struct snd_soc_card *card = dev_get_drvdata(&pdev->dev); 428 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 429 430 snd_soc_unregister_card(card); 431 kfree(card->dai_link); 432 kfree(data); 433 kfree(card); 434 return 0; 435 } 436 437 static const struct of_device_id sdm845_snd_device_id[] = { 438 { .compatible = "qcom,sdm845-sndcard" }, 439 {}, 440 }; 441 MODULE_DEVICE_TABLE(of, sdm845_snd_device_id); 442 443 static struct platform_driver sdm845_snd_driver = { 444 .probe = sdm845_snd_platform_probe, 445 .remove = sdm845_snd_platform_remove, 446 .driver = { 447 .name = "msm-snd-sdm845", 448 .of_match_table = sdm845_snd_device_id, 449 }, 450 }; 451 module_platform_driver(sdm845_snd_driver); 452 453 MODULE_DESCRIPTION("sdm845 ASoC Machine Driver"); 454 MODULE_LICENSE("GPL v2"); 455