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 static const struct { 82 unsigned int rx; 83 } max_98373_tdm_mask[] = { 84 {.rx = 0x3}, 85 {.rx = 0x3}, 86 }; 87 88 /* 89 * The tx mask indicates which channel(s) contains output IV-sense data and 90 * others should set to Hi-Z. Here we get the channel number from codec's ACPI 91 * device property "maxim,vmon-slot-no" and "maxim,imon-slot-no" to generate the 92 * mask. Refer to the max98373_slot_config() function in max98373.c codec driver. 93 */ 94 static unsigned int max_98373_get_tx_mask(struct device *dev) 95 { 96 int vmon_slot; 97 int imon_slot; 98 99 if (device_property_read_u32(dev, "maxim,vmon-slot-no", &vmon_slot)) 100 vmon_slot = 0; 101 102 if (device_property_read_u32(dev, "maxim,imon-slot-no", &imon_slot)) 103 imon_slot = 1; 104 105 dev_dbg(dev, "vmon_slot %d imon_slot %d\n", vmon_slot, imon_slot); 106 107 return (0x1 << vmon_slot) | (0x1 << imon_slot); 108 } 109 110 static int max_98373_hw_params(struct snd_pcm_substream *substream, 111 struct snd_pcm_hw_params *params) 112 { 113 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 114 struct snd_soc_dai_link *dai_link = rtd->dai_link; 115 struct snd_soc_dai *codec_dai; 116 int i; 117 int tdm_slots; 118 unsigned int tx_mask; 119 unsigned int tx_mask_used = 0x0; 120 int ret = 0; 121 122 for_each_rtd_codec_dais(rtd, i, codec_dai) { 123 if (i >= ARRAY_SIZE(max_98373_tdm_mask)) { 124 dev_err(codec_dai->dev, "only 2 amps are supported\n"); 125 return -EINVAL; 126 } 127 128 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 129 case SND_SOC_DAIFMT_DSP_A: 130 case SND_SOC_DAIFMT_DSP_B: 131 /* get the tplg configured tdm slot number */ 132 tdm_slots = sof_dai_get_tdm_slots(rtd); 133 if (tdm_slots <= 0) { 134 dev_err(rtd->dev, "invalid tdm slots %d\n", 135 tdm_slots); 136 return -EINVAL; 137 } 138 139 /* get the tx mask from ACPI device properties */ 140 tx_mask = max_98373_get_tx_mask(codec_dai->dev); 141 if (!tx_mask) 142 return -EINVAL; 143 144 if (tx_mask & tx_mask_used) { 145 dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n", 146 tx_mask, tx_mask_used); 147 return -EINVAL; 148 } 149 150 tx_mask_used |= tx_mask; 151 152 /* 153 * check if tdm slot number is too small for channel 154 * allocation 155 */ 156 if (fls(tx_mask) > tdm_slots) { 157 dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n", 158 fls(tx_mask), tdm_slots); 159 return -EINVAL; 160 } 161 162 if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) { 163 dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n", 164 fls(max_98373_tdm_mask[i].rx), tdm_slots); 165 return -EINVAL; 166 } 167 168 dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n", 169 tx_mask, max_98373_tdm_mask[i].rx, 170 tdm_slots, params_width(params)); 171 172 ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask, 173 max_98373_tdm_mask[i].rx, 174 tdm_slots, 175 params_width(params)); 176 if (ret < 0) { 177 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 178 ret); 179 return ret; 180 } 181 break; 182 default: 183 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 184 break; 185 } 186 } 187 return 0; 188 } 189 190 static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) 191 { 192 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 193 struct snd_soc_dai *codec_dai; 194 struct snd_soc_dai *cpu_dai; 195 int j; 196 int ret = 0; 197 198 /* set spk pin by playback only */ 199 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 200 return 0; 201 202 cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 203 for_each_rtd_codec_dais(rtd, j, codec_dai) { 204 struct snd_soc_dapm_context *dapm = 205 snd_soc_component_get_dapm(cpu_dai->component); 206 char pin_name[MAX_98373_PIN_NAME]; 207 208 snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", 209 codec_dai->component->name_prefix); 210 211 switch (cmd) { 212 case SNDRV_PCM_TRIGGER_START: 213 case SNDRV_PCM_TRIGGER_RESUME: 214 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 215 ret = snd_soc_dapm_enable_pin(dapm, pin_name); 216 if (!ret) 217 snd_soc_dapm_sync(dapm); 218 break; 219 case SNDRV_PCM_TRIGGER_STOP: 220 case SNDRV_PCM_TRIGGER_SUSPEND: 221 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 222 ret = snd_soc_dapm_disable_pin(dapm, pin_name); 223 if (!ret) 224 snd_soc_dapm_sync(dapm); 225 break; 226 default: 227 break; 228 } 229 } 230 231 return ret; 232 } 233 234 static const struct snd_soc_ops max_98373_ops = { 235 .hw_params = max_98373_hw_params, 236 .trigger = max_98373_trigger, 237 }; 238 239 static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 240 { 241 struct snd_soc_card *card = rtd->card; 242 unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID); 243 int ret; 244 245 switch (num_codecs) { 246 case 2: 247 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, 248 ARRAY_SIZE(maxim_2spk_widgets)); 249 if (ret) { 250 dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n", 251 ret); 252 return ret; 253 } 254 255 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, 256 ARRAY_SIZE(maxim_2spk_kcontrols)); 257 if (ret) { 258 dev_err(rtd->dev, "fail to add max98373 kcontrols, ret %d\n", 259 ret); 260 return ret; 261 } 262 263 ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 264 ARRAY_SIZE(max_98373_dapm_routes)); 265 if (ret) { 266 dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n", 267 ret); 268 return ret; 269 } 270 break; 271 default: 272 dev_err(rtd->dev, "max98373: invalid num_codecs %d\n", num_codecs); 273 return -EINVAL; 274 } 275 276 return ret; 277 } 278 279 void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link) 280 { 281 link->codecs = max_98373_components; 282 link->num_codecs = ARRAY_SIZE(max_98373_components); 283 link->init = max_98373_spk_codec_init; 284 link->ops = &max_98373_ops; 285 } 286 EXPORT_SYMBOL_NS(max_98373_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 287 288 void max_98373_set_codec_conf(struct snd_soc_card *card) 289 { 290 card->codec_conf = max_98373_codec_conf; 291 card->num_configs = ARRAY_SIZE(max_98373_codec_conf); 292 } 293 EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); 294 295 /* 296 * Maxim MAX98390 297 */ 298 static const struct snd_soc_dapm_route max_98390_dapm_routes[] = { 299 /* speaker */ 300 { "Left Spk", NULL, "Left BE_OUT" }, 301 { "Right Spk", NULL, "Right BE_OUT" }, 302 }; 303 304 static const struct snd_kcontrol_new max_98390_tt_kcontrols[] = { 305 SOC_DAPM_PIN_SWITCH("TL Spk"), 306 SOC_DAPM_PIN_SWITCH("TR Spk"), 307 }; 308 309 static const struct snd_soc_dapm_widget max_98390_tt_dapm_widgets[] = { 310 SND_SOC_DAPM_SPK("TL Spk", NULL), 311 SND_SOC_DAPM_SPK("TR Spk", NULL), 312 }; 313 314 static const struct snd_soc_dapm_route max_98390_tt_dapm_routes[] = { 315 /* Tweeter speaker */ 316 { "TL Spk", NULL, "Tweeter Left BE_OUT" }, 317 { "TR Spk", NULL, "Tweeter Right BE_OUT" }, 318 }; 319 320 static struct snd_soc_codec_conf max_98390_cml_codec_conf[] = { 321 { 322 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), 323 .name_prefix = "Left", 324 }, 325 { 326 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 327 .name_prefix = "Right", 328 }, 329 }; 330 331 static struct snd_soc_codec_conf max_98390_codec_conf[] = { 332 { 333 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), 334 .name_prefix = "Right", 335 }, 336 { 337 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 338 .name_prefix = "Left", 339 }, 340 { 341 .dlc = COMP_CODEC_CONF(MAX_98390_DEV2_NAME), 342 .name_prefix = "Tweeter Right", 343 }, 344 { 345 .dlc = COMP_CODEC_CONF(MAX_98390_DEV3_NAME), 346 .name_prefix = "Tweeter Left", 347 }, 348 }; 349 350 static struct snd_soc_dai_link_component max_98390_components[] = { 351 { 352 .name = MAX_98390_DEV0_NAME, 353 .dai_name = MAX_98390_CODEC_DAI, 354 }, 355 { 356 .name = MAX_98390_DEV1_NAME, 357 .dai_name = MAX_98390_CODEC_DAI, 358 }, 359 { 360 .name = MAX_98390_DEV2_NAME, 361 .dai_name = MAX_98390_CODEC_DAI, 362 }, 363 { 364 .name = MAX_98390_DEV3_NAME, 365 .dai_name = MAX_98390_CODEC_DAI, 366 }, 367 }; 368 369 static const struct { 370 unsigned int tx; 371 unsigned int rx; 372 } max_98390_tdm_mask[] = { 373 {.tx = 0x01, .rx = 0x3}, 374 {.tx = 0x02, .rx = 0x3}, 375 {.tx = 0x04, .rx = 0x3}, 376 {.tx = 0x08, .rx = 0x3}, 377 }; 378 379 static int max_98390_hw_params(struct snd_pcm_substream *substream, 380 struct snd_pcm_hw_params *params) 381 { 382 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 383 struct snd_soc_dai_link *dai_link = rtd->dai_link; 384 struct snd_soc_dai *codec_dai; 385 int i, ret; 386 387 for_each_rtd_codec_dais(rtd, i, codec_dai) { 388 if (i >= ARRAY_SIZE(max_98390_tdm_mask)) { 389 dev_err(codec_dai->dev, "invalid codec index %d\n", i); 390 return -ENODEV; 391 } 392 393 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 394 case SND_SOC_DAIFMT_DSP_A: 395 case SND_SOC_DAIFMT_DSP_B: 396 /* 4-slot TDM */ 397 ret = snd_soc_dai_set_tdm_slot(codec_dai, 398 max_98390_tdm_mask[i].tx, 399 max_98390_tdm_mask[i].rx, 400 4, 401 params_width(params)); 402 if (ret < 0) { 403 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 404 ret); 405 return ret; 406 } 407 break; 408 default: 409 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 410 break; 411 } 412 } 413 return 0; 414 } 415 416 static int max_98390_init(struct snd_soc_pcm_runtime *rtd) 417 { 418 struct snd_soc_card *card = rtd->card; 419 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 420 int ret; 421 422 switch (num_codecs) { 423 case 4: 424 /* add widgets/controls/dapm for tweeter speakers */ 425 ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets, 426 ARRAY_SIZE(max_98390_tt_dapm_widgets)); 427 if (ret) { 428 dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n", 429 ret); 430 /* Don't need to add routes if widget addition failed */ 431 return ret; 432 } 433 434 ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols, 435 ARRAY_SIZE(max_98390_tt_kcontrols)); 436 if (ret) { 437 dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n", 438 ret); 439 return ret; 440 } 441 442 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes, 443 ARRAY_SIZE(max_98390_tt_dapm_routes)); 444 if (ret) { 445 dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n", 446 ret); 447 return ret; 448 } 449 450 fallthrough; 451 case 2: 452 /* add regular speakers dapm route */ 453 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, 454 ARRAY_SIZE(maxim_2spk_widgets)); 455 if (ret) { 456 dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n", 457 ret); 458 return ret; 459 } 460 461 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, 462 ARRAY_SIZE(maxim_2spk_kcontrols)); 463 if (ret) { 464 dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n", 465 ret); 466 return ret; 467 } 468 469 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, 470 ARRAY_SIZE(max_98390_dapm_routes)); 471 if (ret) { 472 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", 473 ret); 474 return ret; 475 } 476 break; 477 default: 478 dev_err(rtd->dev, "invalid codec number %d\n", num_codecs); 479 return -EINVAL; 480 } 481 482 return ret; 483 } 484 485 static const struct snd_soc_ops max_98390_ops = { 486 .hw_params = max_98390_hw_params, 487 }; 488 489 void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) 490 { 491 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 492 493 link->codecs = max_98390_components; 494 495 switch (num_codecs) { 496 case 2: 497 case 4: 498 link->num_codecs = num_codecs; 499 break; 500 default: 501 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 502 MAX_98390_ACPI_HID); 503 break; 504 } 505 506 link->init = max_98390_init; 507 link->ops = &max_98390_ops; 508 } 509 EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 510 511 void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) 512 { 513 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 514 515 card->codec_conf = max_98390_codec_conf; 516 517 switch (num_codecs) { 518 case 2: 519 if (soc_intel_is_cml()) 520 card->codec_conf = max_98390_cml_codec_conf; 521 522 fallthrough; 523 case 4: 524 card->num_configs = num_codecs; 525 break; 526 default: 527 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 528 MAX_98390_ACPI_HID); 529 break; 530 } 531 } 532 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON); 533 534 /* 535 * Maxim MAX98357A/MAX98360A 536 */ 537 static const struct snd_kcontrol_new max_98357a_kcontrols[] = { 538 SOC_DAPM_PIN_SWITCH("Spk"), 539 }; 540 541 static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = { 542 SND_SOC_DAPM_SPK("Spk", NULL), 543 }; 544 545 static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = { 546 /* speaker */ 547 {"Spk", NULL, "Speaker"}, 548 }; 549 550 static struct snd_soc_dai_link_component max_98357a_components[] = { 551 { 552 .name = MAX_98357A_DEV0_NAME, 553 .dai_name = MAX_98357A_CODEC_DAI, 554 } 555 }; 556 557 static struct snd_soc_dai_link_component max_98360a_components[] = { 558 { 559 .name = MAX_98360A_DEV0_NAME, 560 .dai_name = MAX_98357A_CODEC_DAI, 561 } 562 }; 563 564 static int max_98357a_init(struct snd_soc_pcm_runtime *rtd) 565 { 566 struct snd_soc_card *card = rtd->card; 567 int ret; 568 569 ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets, 570 ARRAY_SIZE(max_98357a_dapm_widgets)); 571 if (ret) { 572 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 573 /* Don't need to add routes if widget addition failed */ 574 return ret; 575 } 576 577 ret = snd_soc_add_card_controls(card, max_98357a_kcontrols, 578 ARRAY_SIZE(max_98357a_kcontrols)); 579 if (ret) { 580 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 581 return ret; 582 } 583 584 ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes, 585 ARRAY_SIZE(max_98357a_dapm_routes)); 586 587 if (ret) 588 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 589 590 return ret; 591 } 592 593 void max_98357a_dai_link(struct snd_soc_dai_link *link) 594 { 595 link->codecs = max_98357a_components; 596 link->num_codecs = ARRAY_SIZE(max_98357a_components); 597 link->init = max_98357a_init; 598 } 599 EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 600 601 void max_98360a_dai_link(struct snd_soc_dai_link *link) 602 { 603 link->codecs = max_98360a_components; 604 link->num_codecs = ARRAY_SIZE(max_98360a_components); 605 link->init = max_98357a_init; 606 } 607 EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 608 609 MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers"); 610 MODULE_LICENSE("GPL"); 611