1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mt8183-mt6358.c -- 4 // MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver 5 // 6 // Copyright (c) 2018 MediaTek Inc. 7 // Author: Shunli Wang <shunli.wang@mediatek.com> 8 9 #include <linux/module.h> 10 #include <sound/pcm_params.h> 11 #include <sound/soc.h> 12 #include <sound/jack.h> 13 #include <linux/pinctrl/consumer.h> 14 15 #include "mt8183-afe-common.h" 16 #include "../../codecs/ts3a227e.h" 17 18 static struct snd_soc_jack headset_jack; 19 20 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 21 struct snd_pcm_hw_params *params) 22 { 23 struct snd_soc_pcm_runtime *rtd = substream->private_data; 24 unsigned int rate = params_rate(params); 25 unsigned int mclk_fs_ratio = 128; 26 unsigned int mclk_fs = rate * mclk_fs_ratio; 27 28 return snd_soc_dai_set_sysclk(rtd->cpu_dai, 29 0, mclk_fs, SND_SOC_CLOCK_OUT); 30 } 31 32 static const struct snd_soc_ops mt8183_mt6358_i2s_ops = { 33 .hw_params = mt8183_mt6358_i2s_hw_params, 34 }; 35 36 static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 37 struct snd_pcm_hw_params *params) 38 { 39 dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__); 40 41 /* fix BE i2s format to 32bit, clean param mask first */ 42 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 43 0, SNDRV_PCM_FORMAT_LAST); 44 45 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 46 return 0; 47 } 48 49 static const struct snd_soc_dapm_widget 50 mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = { 51 SND_SOC_DAPM_OUTPUT("IT6505_8CH"), 52 }; 53 54 static const struct snd_soc_dapm_route 55 mt8183_mt6358_ts3a227_max98357_dapm_routes[] = { 56 {"IT6505_8CH", NULL, "TDM"}, 57 }; 58 59 static int 60 mt8183_mt6358_ts3a227_max98357_bt_sco_startup( 61 struct snd_pcm_substream *substream) 62 { 63 static const unsigned int rates[] = { 64 8000, 16000 65 }; 66 static const struct snd_pcm_hw_constraint_list constraints_rates = { 67 .count = ARRAY_SIZE(rates), 68 .list = rates, 69 .mask = 0, 70 }; 71 static const unsigned int channels[] = { 72 1, 73 }; 74 static const struct snd_pcm_hw_constraint_list constraints_channels = { 75 .count = ARRAY_SIZE(channels), 76 .list = channels, 77 .mask = 0, 78 }; 79 80 struct snd_pcm_runtime *runtime = substream->runtime; 81 82 snd_pcm_hw_constraint_list(runtime, 0, 83 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 84 runtime->hw.channels_max = 1; 85 snd_pcm_hw_constraint_list(runtime, 0, 86 SNDRV_PCM_HW_PARAM_CHANNELS, 87 &constraints_channels); 88 89 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 90 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 91 92 return 0; 93 } 94 95 static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_bt_sco_ops = { 96 .startup = mt8183_mt6358_ts3a227_max98357_bt_sco_startup, 97 }; 98 99 /* FE */ 100 SND_SOC_DAILINK_DEFS(playback1, 101 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 102 DAILINK_COMP_ARRAY(COMP_DUMMY()), 103 DAILINK_COMP_ARRAY(COMP_EMPTY())); 104 105 SND_SOC_DAILINK_DEFS(playback2, 106 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 107 DAILINK_COMP_ARRAY(COMP_DUMMY()), 108 DAILINK_COMP_ARRAY(COMP_EMPTY())); 109 110 SND_SOC_DAILINK_DEFS(playback3, 111 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 112 DAILINK_COMP_ARRAY(COMP_DUMMY()), 113 DAILINK_COMP_ARRAY(COMP_EMPTY())); 114 115 SND_SOC_DAILINK_DEFS(capture1, 116 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 117 DAILINK_COMP_ARRAY(COMP_DUMMY()), 118 DAILINK_COMP_ARRAY(COMP_EMPTY())); 119 120 SND_SOC_DAILINK_DEFS(capture2, 121 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 122 DAILINK_COMP_ARRAY(COMP_DUMMY()), 123 DAILINK_COMP_ARRAY(COMP_EMPTY())); 124 125 SND_SOC_DAILINK_DEFS(capture3, 126 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 127 DAILINK_COMP_ARRAY(COMP_DUMMY()), 128 DAILINK_COMP_ARRAY(COMP_EMPTY())); 129 130 SND_SOC_DAILINK_DEFS(capture_mono, 131 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 132 DAILINK_COMP_ARRAY(COMP_DUMMY()), 133 DAILINK_COMP_ARRAY(COMP_EMPTY())); 134 135 SND_SOC_DAILINK_DEFS(playback_hdmi, 136 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 137 DAILINK_COMP_ARRAY(COMP_DUMMY()), 138 DAILINK_COMP_ARRAY(COMP_EMPTY())); 139 140 /* BE */ 141 SND_SOC_DAILINK_DEFS(primary_codec, 142 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 143 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")), 144 DAILINK_COMP_ARRAY(COMP_EMPTY())); 145 146 SND_SOC_DAILINK_DEFS(pcm1, 147 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 148 DAILINK_COMP_ARRAY(COMP_DUMMY()), 149 DAILINK_COMP_ARRAY(COMP_EMPTY())); 150 151 SND_SOC_DAILINK_DEFS(pcm2, 152 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 153 DAILINK_COMP_ARRAY(COMP_DUMMY()), 154 DAILINK_COMP_ARRAY(COMP_EMPTY())); 155 156 SND_SOC_DAILINK_DEFS(i2s0, 157 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 158 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 159 DAILINK_COMP_ARRAY(COMP_EMPTY())); 160 161 SND_SOC_DAILINK_DEFS(i2s1, 162 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 163 DAILINK_COMP_ARRAY(COMP_DUMMY()), 164 DAILINK_COMP_ARRAY(COMP_EMPTY())); 165 166 SND_SOC_DAILINK_DEFS(i2s2, 167 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 168 DAILINK_COMP_ARRAY(COMP_DUMMY()), 169 DAILINK_COMP_ARRAY(COMP_EMPTY())); 170 171 SND_SOC_DAILINK_DEFS(i2s3, 172 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 173 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi")), 174 DAILINK_COMP_ARRAY(COMP_EMPTY())); 175 176 SND_SOC_DAILINK_DEFS(i2s5, 177 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")), 178 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 179 DAILINK_COMP_ARRAY(COMP_EMPTY())); 180 181 SND_SOC_DAILINK_DEFS(tdm, 182 DAILINK_COMP_ARRAY(COMP_CPU("TDM")), 183 DAILINK_COMP_ARRAY(COMP_DUMMY()), 184 DAILINK_COMP_ARRAY(COMP_EMPTY())); 185 186 static struct snd_soc_dai_link 187 mt8183_mt6358_ts3a227_max98357_dai_links[] = { 188 /* FE */ 189 { 190 .name = "Playback_1", 191 .stream_name = "Playback_1", 192 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 193 SND_SOC_DPCM_TRIGGER_PRE}, 194 .dynamic = 1, 195 .dpcm_playback = 1, 196 SND_SOC_DAILINK_REG(playback1), 197 }, 198 { 199 .name = "Playback_2", 200 .stream_name = "Playback_2", 201 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 202 SND_SOC_DPCM_TRIGGER_PRE}, 203 .dynamic = 1, 204 .dpcm_playback = 1, 205 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops, 206 SND_SOC_DAILINK_REG(playback2), 207 }, 208 { 209 .name = "Playback_3", 210 .stream_name = "Playback_3", 211 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 212 SND_SOC_DPCM_TRIGGER_PRE}, 213 .dynamic = 1, 214 .dpcm_playback = 1, 215 SND_SOC_DAILINK_REG(playback3), 216 }, 217 { 218 .name = "Capture_1", 219 .stream_name = "Capture_1", 220 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 221 SND_SOC_DPCM_TRIGGER_PRE}, 222 .dynamic = 1, 223 .dpcm_capture = 1, 224 .ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops, 225 SND_SOC_DAILINK_REG(capture1), 226 }, 227 { 228 .name = "Capture_2", 229 .stream_name = "Capture_2", 230 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 231 SND_SOC_DPCM_TRIGGER_PRE}, 232 .dynamic = 1, 233 .dpcm_capture = 1, 234 SND_SOC_DAILINK_REG(capture2), 235 }, 236 { 237 .name = "Capture_3", 238 .stream_name = "Capture_3", 239 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 240 SND_SOC_DPCM_TRIGGER_PRE}, 241 .dynamic = 1, 242 .dpcm_capture = 1, 243 SND_SOC_DAILINK_REG(capture3), 244 }, 245 { 246 .name = "Capture_Mono_1", 247 .stream_name = "Capture_Mono_1", 248 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 249 SND_SOC_DPCM_TRIGGER_PRE}, 250 .dynamic = 1, 251 .dpcm_capture = 1, 252 SND_SOC_DAILINK_REG(capture_mono), 253 }, 254 { 255 .name = "Playback_HDMI", 256 .stream_name = "Playback_HDMI", 257 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 258 SND_SOC_DPCM_TRIGGER_PRE}, 259 .dynamic = 1, 260 .dpcm_playback = 1, 261 SND_SOC_DAILINK_REG(playback_hdmi), 262 }, 263 /* BE */ 264 { 265 .name = "Primary Codec", 266 .no_pcm = 1, 267 .dpcm_playback = 1, 268 .dpcm_capture = 1, 269 .ignore_suspend = 1, 270 SND_SOC_DAILINK_REG(primary_codec), 271 }, 272 { 273 .name = "PCM 1", 274 .no_pcm = 1, 275 .dpcm_playback = 1, 276 .dpcm_capture = 1, 277 .ignore_suspend = 1, 278 SND_SOC_DAILINK_REG(pcm1), 279 }, 280 { 281 .name = "PCM 2", 282 .no_pcm = 1, 283 .dpcm_playback = 1, 284 .dpcm_capture = 1, 285 .ignore_suspend = 1, 286 SND_SOC_DAILINK_REG(pcm2), 287 }, 288 { 289 .name = "I2S0", 290 .no_pcm = 1, 291 .dpcm_capture = 1, 292 .ignore_suspend = 1, 293 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 294 .ops = &mt8183_mt6358_i2s_ops, 295 SND_SOC_DAILINK_REG(i2s0), 296 }, 297 { 298 .name = "I2S1", 299 .no_pcm = 1, 300 .dpcm_playback = 1, 301 .ignore_suspend = 1, 302 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 303 .ops = &mt8183_mt6358_i2s_ops, 304 SND_SOC_DAILINK_REG(i2s1), 305 }, 306 { 307 .name = "I2S2", 308 .no_pcm = 1, 309 .dpcm_capture = 1, 310 .ignore_suspend = 1, 311 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 312 .ops = &mt8183_mt6358_i2s_ops, 313 SND_SOC_DAILINK_REG(i2s2), 314 }, 315 { 316 .name = "I2S3", 317 .no_pcm = 1, 318 .dpcm_playback = 1, 319 .ignore_suspend = 1, 320 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 321 .ops = &mt8183_mt6358_i2s_ops, 322 SND_SOC_DAILINK_REG(i2s3), 323 }, 324 { 325 .name = "I2S5", 326 .no_pcm = 1, 327 .dpcm_playback = 1, 328 .ignore_suspend = 1, 329 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 330 .ops = &mt8183_mt6358_i2s_ops, 331 SND_SOC_DAILINK_REG(i2s5), 332 }, 333 { 334 .name = "TDM", 335 .no_pcm = 1, 336 .dpcm_playback = 1, 337 .ignore_suspend = 1, 338 SND_SOC_DAILINK_REG(tdm), 339 }, 340 }; 341 342 static int 343 mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *cpnt); 344 345 static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = { 346 .name = "Headset Chip", 347 .init = mt8183_mt6358_ts3a227_max98357_headset_init, 348 }; 349 350 static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { 351 .name = "mt8183_mt6358_ts3a227_max98357", 352 .owner = THIS_MODULE, 353 .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, 354 .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), 355 .aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev, 356 .num_aux_devs = 1, 357 }; 358 359 static int 360 mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) 361 { 362 int ret; 363 364 /* Enable Headset and 4 Buttons Jack detection */ 365 ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, 366 "Headset Jack", 367 SND_JACK_HEADSET | 368 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 369 SND_JACK_BTN_2 | SND_JACK_BTN_3, 370 &headset_jack, 371 NULL, 0); 372 if (ret) 373 return ret; 374 375 ret = ts3a227e_enable_jack_detect(component, &headset_jack); 376 377 return ret; 378 } 379 380 static int 381 mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) 382 { 383 struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; 384 struct device_node *platform_node; 385 struct snd_soc_dai_link *dai_link; 386 struct pinctrl *default_pins; 387 int i; 388 389 card->dev = &pdev->dev; 390 391 platform_node = of_parse_phandle(pdev->dev.of_node, 392 "mediatek,platform", 0); 393 if (!platform_node) { 394 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 395 return -EINVAL; 396 } 397 398 for_each_card_prelinks(card, i, dai_link) { 399 if (dai_link->platforms->name) 400 continue; 401 dai_link->platforms->of_node = platform_node; 402 } 403 404 mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node = 405 of_parse_phandle(pdev->dev.of_node, 406 "mediatek,headset-codec", 0); 407 if (!mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node) { 408 dev_err(&pdev->dev, 409 "Property 'mediatek,headset-codec' missing/invalid\n"); 410 return -EINVAL; 411 } 412 413 default_pins = 414 devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 415 if (IS_ERR(default_pins)) { 416 dev_err(&pdev->dev, "%s set pins failed\n", 417 __func__); 418 return PTR_ERR(default_pins); 419 } 420 421 return devm_snd_soc_register_card(&pdev->dev, card); 422 } 423 424 #ifdef CONFIG_OF 425 static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = { 426 {.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",}, 427 {} 428 }; 429 #endif 430 431 static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = { 432 .driver = { 433 .name = "mt8183_mt6358_ts3a227_max98357", 434 #ifdef CONFIG_OF 435 .of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match, 436 #endif 437 }, 438 .probe = mt8183_mt6358_ts3a227_max98357_dev_probe, 439 }; 440 441 module_platform_driver(mt8183_mt6358_ts3a227_max98357_driver); 442 443 /* Module information */ 444 MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver"); 445 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 446 MODULE_LICENSE("GPL v2"); 447 MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); 448 449