1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // Copyright(c) 2020 Intel Corporation 4 #include <linux/module.h> 5 #include <linux/string.h> 6 #include <sound/pcm.h> 7 #include <sound/pcm_params.h> 8 #include <sound/soc.h> 9 #include <sound/soc-acpi.h> 10 #include <sound/soc-dai.h> 11 #include <sound/soc-dapm.h> 12 #include <sound/sof.h> 13 #include <uapi/sound/asound.h> 14 #include "../common/soc-intel-quirks.h" 15 #include "sof_maxim_common.h" 16 17 /* 18 * Common structures and functions 19 */ 20 static const struct snd_kcontrol_new maxim_2spk_kcontrols[] = { 21 SOC_DAPM_PIN_SWITCH("Left Spk"), 22 SOC_DAPM_PIN_SWITCH("Right Spk"), 23 24 }; 25 26 static const struct snd_soc_dapm_widget maxim_2spk_widgets[] = { 27 SND_SOC_DAPM_SPK("Left Spk", NULL), 28 SND_SOC_DAPM_SPK("Right Spk", NULL), 29 }; 30 31 /* helper function to get the number of specific codec */ 32 static unsigned int get_num_codecs(const char *hid) 33 { 34 struct acpi_device *adev; 35 unsigned int dev_num = 0; 36 37 for_each_acpi_dev_match(adev, hid, NULL, -1) 38 dev_num++; 39 40 return dev_num; 41 } 42 43 /* 44 * Maxim MAX98373 45 */ 46 #define MAX_98373_PIN_NAME 16 47 48 static const struct snd_soc_dapm_route max_98373_dapm_routes[] = { 49 /* speaker */ 50 { "Left Spk", NULL, "Left BE_OUT" }, 51 { "Right Spk", NULL, "Right BE_OUT" }, 52 }; 53 54 static struct snd_soc_codec_conf max_98373_codec_conf[] = { 55 { 56 .dlc = COMP_CODEC_CONF(MAX_98373_DEV0_NAME), 57 .name_prefix = "Right", 58 }, 59 { 60 .dlc = COMP_CODEC_CONF(MAX_98373_DEV1_NAME), 61 .name_prefix = "Left", 62 }, 63 }; 64 65 static struct snd_soc_dai_link_component max_98373_components[] = { 66 { /* For Right */ 67 .name = MAX_98373_DEV0_NAME, 68 .dai_name = MAX_98373_CODEC_DAI, 69 }, 70 { /* For Left */ 71 .name = MAX_98373_DEV1_NAME, 72 .dai_name = MAX_98373_CODEC_DAI, 73 }, 74 }; 75 76 /* 77 * According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask 78 * should choose two channels from TDM slots, the LSB of rx mask is left channel 79 * and the other one is right channel. 80 * 81 * For tx mask, each codec requires two channels: one for V-sense and the other 82 * one for I-sense. Must match the device property "maxim,vmon-slot-no" and 83 * "maxim,imon-slot-no" in ACPI table. 84 */ 85 static const struct { 86 unsigned int tx; 87 unsigned int rx; 88 } max_98373_tdm_mask[] = { 89 {.tx = 0x03, .rx = 0x3}, 90 {.tx = 0x0c, .rx = 0x3}, 91 }; 92 93 static int max_98373_hw_params(struct snd_pcm_substream *substream, 94 struct snd_pcm_hw_params *params) 95 { 96 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 97 struct snd_soc_dai_link *dai_link = rtd->dai_link; 98 struct snd_soc_dai *codec_dai; 99 int i; 100 int tdm_slots; 101 int ret = 0; 102 103 for_each_rtd_codec_dais(rtd, i, codec_dai) { 104 if (i >= ARRAY_SIZE(max_98373_tdm_mask)) { 105 dev_err(codec_dai->dev, "only 2 amps are supported\n"); 106 return -EINVAL; 107 } 108 109 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 110 case SND_SOC_DAIFMT_DSP_A: 111 case SND_SOC_DAIFMT_DSP_B: 112 /* get the tplg configured tdm slot number */ 113 tdm_slots = sof_dai_get_tdm_slots(rtd); 114 if (tdm_slots <= 0) { 115 dev_err(rtd->dev, "invalid tdm slots %d\n", 116 tdm_slots); 117 return -EINVAL; 118 } 119 120 /* 121 * check if tdm slot number is too small for channel 122 * allocation 123 */ 124 if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) { 125 dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n", 126 fls(max_98373_tdm_mask[i].tx), tdm_slots); 127 return -EINVAL; 128 } 129 130 if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) { 131 dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n", 132 fls(max_98373_tdm_mask[i].rx), tdm_slots); 133 return -EINVAL; 134 } 135 136 dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n", 137 max_98373_tdm_mask[i].tx, 138 max_98373_tdm_mask[i].rx, 139 tdm_slots, params_width(params)); 140 141 ret = snd_soc_dai_set_tdm_slot(codec_dai, 142 max_98373_tdm_mask[i].tx, 143 max_98373_tdm_mask[i].rx, 144 tdm_slots, 145 params_width(params)); 146 if (ret < 0) { 147 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 148 ret); 149 return ret; 150 } 151 break; 152 default: 153 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 154 break; 155 } 156 } 157 return 0; 158 } 159 160 static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) 161 { 162 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 163 struct snd_soc_dai *codec_dai; 164 struct snd_soc_dai *cpu_dai; 165 int j; 166 int ret = 0; 167 168 /* set spk pin by playback only */ 169 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 170 return 0; 171 172 cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 173 for_each_rtd_codec_dais(rtd, j, codec_dai) { 174 struct snd_soc_dapm_context *dapm = 175 snd_soc_component_get_dapm(cpu_dai->component); 176 char pin_name[MAX_98373_PIN_NAME]; 177 178 snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", 179 codec_dai->component->name_prefix); 180 181 switch (cmd) { 182 case SNDRV_PCM_TRIGGER_START: 183 case SNDRV_PCM_TRIGGER_RESUME: 184 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 185 ret = snd_soc_dapm_enable_pin(dapm, pin_name); 186 if (!ret) 187 snd_soc_dapm_sync(dapm); 188 break; 189 case SNDRV_PCM_TRIGGER_STOP: 190 case SNDRV_PCM_TRIGGER_SUSPEND: 191 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 192 ret = snd_soc_dapm_disable_pin(dapm, pin_name); 193 if (!ret) 194 snd_soc_dapm_sync(dapm); 195 break; 196 default: 197 break; 198 } 199 } 200 201 return ret; 202 } 203 204 static const struct snd_soc_ops max_98373_ops = { 205 .hw_params = max_98373_hw_params, 206 .trigger = max_98373_trigger, 207 }; 208 209 static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 210 { 211 struct snd_soc_card *card = rtd->card; 212 unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID); 213 int ret; 214 215 switch (num_codecs) { 216 case 2: 217 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, 218 ARRAY_SIZE(maxim_2spk_widgets)); 219 if (ret) { 220 dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n", 221 ret); 222 return ret; 223 } 224 225 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, 226 ARRAY_SIZE(maxim_2spk_kcontrols)); 227 if (ret) { 228 dev_err(rtd->dev, "fail to add max98373 kcontrols, ret %d\n", 229 ret); 230 return ret; 231 } 232 233 ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 234 ARRAY_SIZE(max_98373_dapm_routes)); 235 if (ret) { 236 dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n", 237 ret); 238 return ret; 239 } 240 break; 241 default: 242 dev_err(rtd->dev, "max98373: invalid num_codecs %d\n", num_codecs); 243 return -EINVAL; 244 } 245 246 return ret; 247 } 248 249 void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link) 250 { 251 link->codecs = max_98373_components; 252 link->num_codecs = ARRAY_SIZE(max_98373_components); 253 link->init = max_98373_spk_codec_init; 254 link->ops = &max_98373_ops; 255 } 256 EXPORT_SYMBOL_NS(max_98373_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 257 258 void max_98373_set_codec_conf(struct snd_soc_card *card) 259 { 260 card->codec_conf = max_98373_codec_conf; 261 card->num_configs = ARRAY_SIZE(max_98373_codec_conf); 262 } 263 EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); 264 265 /* 266 * Maxim MAX98390 267 */ 268 static const struct snd_soc_dapm_route max_98390_dapm_routes[] = { 269 /* speaker */ 270 { "Left Spk", NULL, "Left BE_OUT" }, 271 { "Right Spk", NULL, "Right BE_OUT" }, 272 }; 273 274 static const struct snd_kcontrol_new max_98390_tt_kcontrols[] = { 275 SOC_DAPM_PIN_SWITCH("TL Spk"), 276 SOC_DAPM_PIN_SWITCH("TR Spk"), 277 }; 278 279 static const struct snd_soc_dapm_widget max_98390_tt_dapm_widgets[] = { 280 SND_SOC_DAPM_SPK("TL Spk", NULL), 281 SND_SOC_DAPM_SPK("TR Spk", NULL), 282 }; 283 284 static const struct snd_soc_dapm_route max_98390_tt_dapm_routes[] = { 285 /* Tweeter speaker */ 286 { "TL Spk", NULL, "Tweeter Left BE_OUT" }, 287 { "TR Spk", NULL, "Tweeter Right BE_OUT" }, 288 }; 289 290 static struct snd_soc_codec_conf max_98390_cml_codec_conf[] = { 291 { 292 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), 293 .name_prefix = "Left", 294 }, 295 { 296 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 297 .name_prefix = "Right", 298 }, 299 }; 300 301 static struct snd_soc_codec_conf max_98390_codec_conf[] = { 302 { 303 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), 304 .name_prefix = "Right", 305 }, 306 { 307 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 308 .name_prefix = "Left", 309 }, 310 { 311 .dlc = COMP_CODEC_CONF(MAX_98390_DEV2_NAME), 312 .name_prefix = "Tweeter Right", 313 }, 314 { 315 .dlc = COMP_CODEC_CONF(MAX_98390_DEV3_NAME), 316 .name_prefix = "Tweeter Left", 317 }, 318 }; 319 320 static struct snd_soc_dai_link_component max_98390_components[] = { 321 { 322 .name = MAX_98390_DEV0_NAME, 323 .dai_name = MAX_98390_CODEC_DAI, 324 }, 325 { 326 .name = MAX_98390_DEV1_NAME, 327 .dai_name = MAX_98390_CODEC_DAI, 328 }, 329 { 330 .name = MAX_98390_DEV2_NAME, 331 .dai_name = MAX_98390_CODEC_DAI, 332 }, 333 { 334 .name = MAX_98390_DEV3_NAME, 335 .dai_name = MAX_98390_CODEC_DAI, 336 }, 337 }; 338 339 static const struct { 340 unsigned int tx; 341 unsigned int rx; 342 } max_98390_tdm_mask[] = { 343 {.tx = 0x01, .rx = 0x3}, 344 {.tx = 0x02, .rx = 0x3}, 345 {.tx = 0x04, .rx = 0x3}, 346 {.tx = 0x08, .rx = 0x3}, 347 }; 348 349 static int max_98390_hw_params(struct snd_pcm_substream *substream, 350 struct snd_pcm_hw_params *params) 351 { 352 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 353 struct snd_soc_dai_link *dai_link = rtd->dai_link; 354 struct snd_soc_dai *codec_dai; 355 int i, ret; 356 357 for_each_rtd_codec_dais(rtd, i, codec_dai) { 358 if (i >= ARRAY_SIZE(max_98390_tdm_mask)) { 359 dev_err(codec_dai->dev, "invalid codec index %d\n", i); 360 return -ENODEV; 361 } 362 363 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 364 case SND_SOC_DAIFMT_DSP_A: 365 case SND_SOC_DAIFMT_DSP_B: 366 /* 4-slot TDM */ 367 ret = snd_soc_dai_set_tdm_slot(codec_dai, 368 max_98390_tdm_mask[i].tx, 369 max_98390_tdm_mask[i].rx, 370 4, 371 params_width(params)); 372 if (ret < 0) { 373 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 374 ret); 375 return ret; 376 } 377 break; 378 default: 379 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 380 break; 381 } 382 } 383 return 0; 384 } 385 386 static int max_98390_init(struct snd_soc_pcm_runtime *rtd) 387 { 388 struct snd_soc_card *card = rtd->card; 389 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 390 int ret; 391 392 switch (num_codecs) { 393 case 4: 394 /* add widgets/controls/dapm for tweeter speakers */ 395 ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets, 396 ARRAY_SIZE(max_98390_tt_dapm_widgets)); 397 if (ret) { 398 dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n", 399 ret); 400 /* Don't need to add routes if widget addition failed */ 401 return ret; 402 } 403 404 ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols, 405 ARRAY_SIZE(max_98390_tt_kcontrols)); 406 if (ret) { 407 dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n", 408 ret); 409 return ret; 410 } 411 412 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes, 413 ARRAY_SIZE(max_98390_tt_dapm_routes)); 414 if (ret) { 415 dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n", 416 ret); 417 return ret; 418 } 419 420 fallthrough; 421 case 2: 422 /* add regular speakers dapm route */ 423 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, 424 ARRAY_SIZE(maxim_2spk_widgets)); 425 if (ret) { 426 dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n", 427 ret); 428 return ret; 429 } 430 431 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, 432 ARRAY_SIZE(maxim_2spk_kcontrols)); 433 if (ret) { 434 dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n", 435 ret); 436 return ret; 437 } 438 439 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, 440 ARRAY_SIZE(max_98390_dapm_routes)); 441 if (ret) { 442 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", 443 ret); 444 return ret; 445 } 446 break; 447 default: 448 dev_err(rtd->dev, "invalid codec number %d\n", num_codecs); 449 return -EINVAL; 450 } 451 452 return ret; 453 } 454 455 static const struct snd_soc_ops max_98390_ops = { 456 .hw_params = max_98390_hw_params, 457 }; 458 459 void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) 460 { 461 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 462 463 link->codecs = max_98390_components; 464 465 switch (num_codecs) { 466 case 2: 467 case 4: 468 link->num_codecs = num_codecs; 469 break; 470 default: 471 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 472 MAX_98390_ACPI_HID); 473 break; 474 } 475 476 link->init = max_98390_init; 477 link->ops = &max_98390_ops; 478 } 479 EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 480 481 void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) 482 { 483 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 484 485 card->codec_conf = max_98390_codec_conf; 486 487 switch (num_codecs) { 488 case 2: 489 if (soc_intel_is_cml()) 490 card->codec_conf = max_98390_cml_codec_conf; 491 492 fallthrough; 493 case 4: 494 card->num_configs = num_codecs; 495 break; 496 default: 497 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 498 MAX_98390_ACPI_HID); 499 break; 500 } 501 } 502 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); 503 504 /* 505 * Maxim MAX98357A/MAX98360A 506 */ 507 static const struct snd_kcontrol_new max_98357a_kcontrols[] = { 508 SOC_DAPM_PIN_SWITCH("Spk"), 509 }; 510 511 static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = { 512 SND_SOC_DAPM_SPK("Spk", NULL), 513 }; 514 515 static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = { 516 /* speaker */ 517 {"Spk", NULL, "Speaker"}, 518 }; 519 520 static struct snd_soc_dai_link_component max_98357a_components[] = { 521 { 522 .name = MAX_98357A_DEV0_NAME, 523 .dai_name = MAX_98357A_CODEC_DAI, 524 } 525 }; 526 527 static struct snd_soc_dai_link_component max_98360a_components[] = { 528 { 529 .name = MAX_98360A_DEV0_NAME, 530 .dai_name = MAX_98357A_CODEC_DAI, 531 } 532 }; 533 534 static int max_98357a_init(struct snd_soc_pcm_runtime *rtd) 535 { 536 struct snd_soc_card *card = rtd->card; 537 int ret; 538 539 ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets, 540 ARRAY_SIZE(max_98357a_dapm_widgets)); 541 if (ret) { 542 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 543 /* Don't need to add routes if widget addition failed */ 544 return ret; 545 } 546 547 ret = snd_soc_add_card_controls(card, max_98357a_kcontrols, 548 ARRAY_SIZE(max_98357a_kcontrols)); 549 if (ret) { 550 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 551 return ret; 552 } 553 554 ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes, 555 ARRAY_SIZE(max_98357a_dapm_routes)); 556 557 if (ret) 558 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 559 560 return ret; 561 } 562 563 void max_98357a_dai_link(struct snd_soc_dai_link *link) 564 { 565 link->codecs = max_98357a_components; 566 link->num_codecs = ARRAY_SIZE(max_98357a_components); 567 link->init = max_98357a_init; 568 } 569 EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 570 571 void max_98360a_dai_link(struct snd_soc_dai_link *link) 572 { 573 link->codecs = max_98360a_components; 574 link->num_codecs = ARRAY_SIZE(max_98360a_components); 575 link->init = max_98357a_init; 576 } 577 EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 578 579 MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers"); 580 MODULE_LICENSE("GPL"); 581