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 = snd_soc_component_to_dapm(cpu_dai->component); 205 char pin_name[MAX_98373_PIN_NAME]; 206 207 snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", 208 codec_dai->component->name_prefix); 209 210 switch (cmd) { 211 case SNDRV_PCM_TRIGGER_START: 212 case SNDRV_PCM_TRIGGER_RESUME: 213 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 214 ret = snd_soc_dapm_enable_pin(dapm, pin_name); 215 if (!ret) 216 snd_soc_dapm_sync(dapm); 217 break; 218 case SNDRV_PCM_TRIGGER_STOP: 219 case SNDRV_PCM_TRIGGER_SUSPEND: 220 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 221 ret = snd_soc_dapm_disable_pin(dapm, pin_name); 222 if (!ret) 223 snd_soc_dapm_sync(dapm); 224 break; 225 default: 226 break; 227 } 228 } 229 230 return ret; 231 } 232 233 static const struct snd_soc_ops max_98373_ops = { 234 .hw_params = max_98373_hw_params, 235 .trigger = max_98373_trigger, 236 }; 237 238 static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 239 { 240 struct snd_soc_card *card = rtd->card; 241 struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(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(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(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 struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); 420 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 421 int ret; 422 423 switch (num_codecs) { 424 case 4: 425 /* add widgets/controls/dapm for tweeter speakers */ 426 ret = snd_soc_dapm_new_controls(dapm, max_98390_tt_dapm_widgets, 427 ARRAY_SIZE(max_98390_tt_dapm_widgets)); 428 if (ret) { 429 dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n", 430 ret); 431 /* Don't need to add routes if widget addition failed */ 432 return ret; 433 } 434 435 ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols, 436 ARRAY_SIZE(max_98390_tt_kcontrols)); 437 if (ret) { 438 dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n", 439 ret); 440 return ret; 441 } 442 443 ret = snd_soc_dapm_add_routes(dapm, max_98390_tt_dapm_routes, 444 ARRAY_SIZE(max_98390_tt_dapm_routes)); 445 if (ret) { 446 dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n", 447 ret); 448 return ret; 449 } 450 451 fallthrough; 452 case 2: 453 /* add regular speakers dapm route */ 454 ret = snd_soc_dapm_new_controls(dapm, maxim_2spk_widgets, 455 ARRAY_SIZE(maxim_2spk_widgets)); 456 if (ret) { 457 dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n", 458 ret); 459 return ret; 460 } 461 462 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols, 463 ARRAY_SIZE(maxim_2spk_kcontrols)); 464 if (ret) { 465 dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n", 466 ret); 467 return ret; 468 } 469 470 ret = snd_soc_dapm_add_routes(dapm, max_98390_dapm_routes, 471 ARRAY_SIZE(max_98390_dapm_routes)); 472 if (ret) { 473 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", 474 ret); 475 return ret; 476 } 477 break; 478 default: 479 dev_err(rtd->dev, "invalid codec number %d\n", num_codecs); 480 return -EINVAL; 481 } 482 483 return ret; 484 } 485 486 static const struct snd_soc_ops max_98390_ops = { 487 .hw_params = max_98390_hw_params, 488 }; 489 490 void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) 491 { 492 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 493 494 link->codecs = max_98390_components; 495 496 switch (num_codecs) { 497 case 2: 498 case 4: 499 link->num_codecs = num_codecs; 500 break; 501 default: 502 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 503 MAX_98390_ACPI_HID); 504 break; 505 } 506 507 link->init = max_98390_init; 508 link->ops = &max_98390_ops; 509 } 510 EXPORT_SYMBOL_NS(max_98390_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); 511 512 void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) 513 { 514 unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 515 516 card->codec_conf = max_98390_codec_conf; 517 518 switch (num_codecs) { 519 case 2: 520 if (soc_intel_is_cml()) 521 card->codec_conf = max_98390_cml_codec_conf; 522 523 fallthrough; 524 case 4: 525 card->num_configs = num_codecs; 526 break; 527 default: 528 dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 529 MAX_98390_ACPI_HID); 530 break; 531 } 532 } 533 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); 534 535 /* 536 * Maxim MAX98357A/MAX98360A 537 */ 538 static const struct snd_kcontrol_new max_98357a_kcontrols[] = { 539 SOC_DAPM_PIN_SWITCH("Spk"), 540 }; 541 542 static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = { 543 SND_SOC_DAPM_SPK("Spk", NULL), 544 }; 545 546 static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = { 547 /* speaker */ 548 {"Spk", NULL, "Speaker"}, 549 }; 550 551 static struct snd_soc_dai_link_component max_98357a_components[] = { 552 { 553 .name = MAX_98357A_DEV0_NAME, 554 .dai_name = MAX_98357A_CODEC_DAI, 555 } 556 }; 557 558 static struct snd_soc_dai_link_component max_98360a_components[] = { 559 { 560 .name = MAX_98360A_DEV0_NAME, 561 .dai_name = MAX_98357A_CODEC_DAI, 562 } 563 }; 564 565 static int max_98357a_init(struct snd_soc_pcm_runtime *rtd) 566 { 567 struct snd_soc_card *card = rtd->card; 568 struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); 569 int ret; 570 571 ret = snd_soc_dapm_new_controls(dapm, max_98357a_dapm_widgets, 572 ARRAY_SIZE(max_98357a_dapm_widgets)); 573 if (ret) { 574 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); 575 /* Don't need to add routes if widget addition failed */ 576 return ret; 577 } 578 579 ret = snd_soc_add_card_controls(card, max_98357a_kcontrols, 580 ARRAY_SIZE(max_98357a_kcontrols)); 581 if (ret) { 582 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); 583 return ret; 584 } 585 586 ret = snd_soc_dapm_add_routes(dapm, max_98357a_dapm_routes, 587 ARRAY_SIZE(max_98357a_dapm_routes)); 588 589 if (ret) 590 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); 591 592 return ret; 593 } 594 595 void max_98357a_dai_link(struct snd_soc_dai_link *link) 596 { 597 link->codecs = max_98357a_components; 598 link->num_codecs = ARRAY_SIZE(max_98357a_components); 599 link->init = max_98357a_init; 600 } 601 EXPORT_SYMBOL_NS(max_98357a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); 602 603 void max_98360a_dai_link(struct snd_soc_dai_link *link) 604 { 605 link->codecs = max_98360a_components; 606 link->num_codecs = ARRAY_SIZE(max_98360a_components); 607 link->init = max_98357a_init; 608 } 609 EXPORT_SYMBOL_NS(max_98360a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON"); 610 611 MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers"); 612 MODULE_LICENSE("GPL"); 613