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