1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // Midas audio support 4 // 5 // Copyright (C) 2018 Simon Shields <simon@lineageos.org> 6 // Copyright (C) 2020 Samsung Electronics Co., Ltd. 7 8 #include <linux/clk.h> 9 #include <linux/gpio/consumer.h> 10 #include <linux/mfd/wm8994/registers.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/regulator/consumer.h> 14 #include <sound/jack.h> 15 #include <sound/soc.h> 16 #include <sound/soc-dapm.h> 17 18 #include "i2s.h" 19 #include "../codecs/wm8994.h" 20 21 /* 22 * The MCLK1 clock source is XCLKOUT with its mux set to the external fixed rate 23 * oscillator (XXTI). 24 */ 25 #define MCLK1_RATE 24000000U 26 #define MCLK2_RATE 32768U 27 #define DEFAULT_FLL1_RATE 11289600U 28 29 struct midas_priv { 30 struct regulator *reg_mic_bias; 31 struct regulator *reg_submic_bias; 32 struct gpio_desc *gpio_fm_sel; 33 struct gpio_desc *gpio_lineout_sel; 34 unsigned int fll1_rate; 35 36 struct snd_soc_jack headset_jack; 37 }; 38 39 static struct snd_soc_jack_pin headset_jack_pins[] = { 40 { 41 .pin = "Headphone", 42 .mask = SND_JACK_HEADPHONE, 43 }, 44 { 45 .pin = "Headset Mic", 46 .mask = SND_JACK_MICROPHONE, 47 }, 48 }; 49 50 static int midas_start_fll1(struct snd_soc_pcm_runtime *rtd, unsigned int rate) 51 { 52 struct snd_soc_card *card = rtd->card; 53 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 54 struct snd_soc_dai *aif1_dai = snd_soc_rtd_to_codec(rtd, 0); 55 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 56 int ret; 57 58 if (!rate) 59 rate = priv->fll1_rate; 60 /* 61 * If no new rate is requested, set FLL1 to a sane default for jack 62 * detection. 63 */ 64 if (!rate) 65 rate = DEFAULT_FLL1_RATE; 66 67 if (rate != priv->fll1_rate && priv->fll1_rate) { 68 /* while reconfiguring, switch to MCLK2 for SYSCLK */ 69 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 70 MCLK2_RATE, SND_SOC_CLOCK_IN); 71 if (ret < 0) { 72 dev_err(card->dev, "Unable to switch to MCLK2: %d\n", ret); 73 return ret; 74 } 75 } 76 77 ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, 78 MCLK1_RATE, rate); 79 if (ret < 0) { 80 dev_err(card->dev, "Failed to set FLL1 rate: %d\n", ret); 81 return ret; 82 } 83 priv->fll1_rate = rate; 84 85 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_FLL1, 86 priv->fll1_rate, SND_SOC_CLOCK_IN); 87 if (ret < 0) { 88 dev_err(card->dev, "Failed to set SYSCLK source: %d\n", ret); 89 return ret; 90 } 91 92 ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK, 0, 93 SAMSUNG_I2S_OPCLK_PCLK); 94 if (ret < 0) { 95 dev_err(card->dev, "Failed to set OPCLK source: %d\n", ret); 96 return ret; 97 } 98 99 return 0; 100 } 101 102 static int midas_stop_fll1(struct snd_soc_pcm_runtime *rtd) 103 { 104 struct snd_soc_card *card = rtd->card; 105 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 106 struct snd_soc_dai *aif1_dai = snd_soc_rtd_to_codec(rtd, 0); 107 int ret; 108 109 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 110 MCLK2_RATE, SND_SOC_CLOCK_IN); 111 if (ret < 0) { 112 dev_err(card->dev, "Unable to switch to MCLK2: %d\n", ret); 113 return ret; 114 } 115 116 ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1, 0, 0, 0); 117 if (ret < 0) { 118 dev_err(card->dev, "Unable to stop FLL1: %d\n", ret); 119 return ret; 120 } 121 122 priv->fll1_rate = 0; 123 124 return 0; 125 } 126 127 static int midas_aif1_hw_params(struct snd_pcm_substream *substream, 128 struct snd_pcm_hw_params *params) 129 { 130 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 131 unsigned int pll_out; 132 133 /* AIF1CLK should be at least 3MHz for "optimal performance" */ 134 if (params_rate(params) == 8000 || params_rate(params) == 11025) 135 pll_out = params_rate(params) * 512; 136 else 137 pll_out = params_rate(params) * 256; 138 139 return midas_start_fll1(rtd, pll_out); 140 } 141 142 static const struct snd_soc_ops midas_aif1_ops = { 143 .hw_params = midas_aif1_hw_params, 144 }; 145 146 /* 147 * We only have a single external speaker, so mix stereo data 148 * to a single mono stream. 149 */ 150 static int midas_ext_spkmode(struct snd_soc_dapm_widget *w, 151 struct snd_kcontrol *kcontrol, int event) 152 { 153 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); 154 int ret = 0; 155 156 switch (event) { 157 case SND_SOC_DAPM_PRE_PMU: 158 ret = snd_soc_component_update_bits(codec, WM8994_SPKOUT_MIXERS, 159 WM8994_SPKMIXR_TO_SPKOUTL_MASK, 160 WM8994_SPKMIXR_TO_SPKOUTL); 161 break; 162 case SND_SOC_DAPM_POST_PMD: 163 ret = snd_soc_component_update_bits(codec, WM8994_SPKOUT_MIXERS, 164 WM8994_SPKMIXR_TO_SPKOUTL_MASK, 165 0); 166 break; 167 } 168 169 return ret; 170 } 171 172 static int midas_mic_bias(struct snd_soc_dapm_widget *w, 173 struct snd_kcontrol *kcontrol, int event) 174 { 175 struct snd_soc_card *card = w->dapm->card; 176 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 177 178 switch (event) { 179 case SND_SOC_DAPM_PRE_PMU: 180 return regulator_enable(priv->reg_mic_bias); 181 case SND_SOC_DAPM_POST_PMD: 182 return regulator_disable(priv->reg_mic_bias); 183 } 184 185 return 0; 186 } 187 188 static int midas_submic_bias(struct snd_soc_dapm_widget *w, 189 struct snd_kcontrol *kcontrol, int event) 190 { 191 struct snd_soc_card *card = w->dapm->card; 192 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 193 194 switch (event) { 195 case SND_SOC_DAPM_PRE_PMU: 196 return regulator_enable(priv->reg_submic_bias); 197 case SND_SOC_DAPM_POST_PMD: 198 return regulator_disable(priv->reg_submic_bias); 199 } 200 201 return 0; 202 } 203 204 static int midas_fm_set(struct snd_soc_dapm_widget *w, 205 struct snd_kcontrol *kcontrol, int event) 206 { 207 struct snd_soc_card *card = w->dapm->card; 208 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 209 210 if (!priv->gpio_fm_sel) 211 return 0; 212 213 switch (event) { 214 case SND_SOC_DAPM_PRE_PMU: 215 gpiod_set_value_cansleep(priv->gpio_fm_sel, 1); 216 break; 217 case SND_SOC_DAPM_POST_PMD: 218 gpiod_set_value_cansleep(priv->gpio_fm_sel, 0); 219 break; 220 } 221 222 return 0; 223 } 224 225 static int midas_line_set(struct snd_soc_dapm_widget *w, 226 struct snd_kcontrol *kcontrol, int event) 227 { 228 struct snd_soc_card *card = w->dapm->card; 229 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 230 231 if (!priv->gpio_lineout_sel) 232 return 0; 233 234 switch (event) { 235 case SND_SOC_DAPM_PRE_PMU: 236 gpiod_set_value_cansleep(priv->gpio_lineout_sel, 1); 237 break; 238 case SND_SOC_DAPM_POST_PMD: 239 gpiod_set_value_cansleep(priv->gpio_lineout_sel, 0); 240 break; 241 } 242 243 return 0; 244 } 245 246 static const struct snd_kcontrol_new midas_controls[] = { 247 SOC_DAPM_PIN_SWITCH("HP"), 248 249 SOC_DAPM_PIN_SWITCH("SPK"), 250 SOC_DAPM_PIN_SWITCH("RCV"), 251 252 SOC_DAPM_PIN_SWITCH("LINE"), 253 SOC_DAPM_PIN_SWITCH("HDMI"), 254 255 SOC_DAPM_PIN_SWITCH("Main Mic"), 256 SOC_DAPM_PIN_SWITCH("Sub Mic"), 257 SOC_DAPM_PIN_SWITCH("Headset Mic"), 258 259 SOC_DAPM_PIN_SWITCH("FM In"), 260 }; 261 262 static const struct snd_soc_dapm_widget midas_dapm_widgets[] = { 263 SND_SOC_DAPM_HP("HP", NULL), 264 265 SND_SOC_DAPM_SPK("SPK", midas_ext_spkmode), 266 SND_SOC_DAPM_SPK("RCV", NULL), 267 268 /* FIXME: toggle MAX77693 on i9300/i9305 */ 269 SND_SOC_DAPM_LINE("LINE", midas_line_set), 270 SND_SOC_DAPM_LINE("HDMI", NULL), 271 SND_SOC_DAPM_LINE("FM In", midas_fm_set), 272 273 SND_SOC_DAPM_HP("Headphone", NULL), 274 SND_SOC_DAPM_MIC("Headset Mic", NULL), 275 SND_SOC_DAPM_MIC("Main Mic", midas_mic_bias), 276 SND_SOC_DAPM_MIC("Sub Mic", midas_submic_bias), 277 }; 278 279 static int midas_set_bias_level(struct snd_soc_card *card, 280 struct snd_soc_dapm_context *dapm, 281 enum snd_soc_bias_level level) 282 { 283 struct snd_soc_pcm_runtime *rtd = snd_soc_get_pcm_runtime(card, 284 &card->dai_link[0]); 285 struct snd_soc_dai *aif1_dai = snd_soc_rtd_to_codec(rtd, 0); 286 287 if (dapm->dev != aif1_dai->dev) 288 return 0; 289 290 switch (level) { 291 case SND_SOC_BIAS_STANDBY: 292 return midas_stop_fll1(rtd); 293 case SND_SOC_BIAS_PREPARE: 294 return midas_start_fll1(rtd, 0); 295 default: 296 break; 297 } 298 299 return 0; 300 } 301 302 static int midas_late_probe(struct snd_soc_card *card) 303 { 304 struct snd_soc_pcm_runtime *rtd = snd_soc_get_pcm_runtime(card, 305 &card->dai_link[0]); 306 struct snd_soc_dai *aif1_dai = snd_soc_rtd_to_codec(rtd, 0); 307 struct midas_priv *priv = snd_soc_card_get_drvdata(card); 308 int ret; 309 310 /* Use MCLK2 as SYSCLK for boot */ 311 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, MCLK2_RATE, 312 SND_SOC_CLOCK_IN); 313 if (ret < 0) { 314 dev_err(aif1_dai->dev, "Failed to switch to MCLK2: %d\n", ret); 315 return ret; 316 } 317 318 ret = snd_soc_card_jack_new_pins(card, "Headset", 319 SND_JACK_HEADSET | SND_JACK_MECHANICAL | 320 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | 321 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5, 322 &priv->headset_jack, 323 headset_jack_pins, 324 ARRAY_SIZE(headset_jack_pins)); 325 if (ret) 326 return ret; 327 328 wm8958_mic_detect(aif1_dai->component, &priv->headset_jack, 329 NULL, NULL, NULL, NULL); 330 return 0; 331 } 332 333 static struct snd_soc_dai_driver midas_ext_dai[] = { 334 { 335 .name = "Voice call", 336 .playback = { 337 .channels_min = 1, 338 .channels_max = 2, 339 .rate_min = 8000, 340 .rate_max = 16000, 341 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), 342 .formats = SNDRV_PCM_FMTBIT_S16_LE, 343 }, 344 .capture = { 345 .channels_min = 1, 346 .channels_max = 2, 347 .rate_min = 8000, 348 .rate_max = 16000, 349 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), 350 .formats = SNDRV_PCM_FMTBIT_S16_LE, 351 }, 352 }, 353 { 354 .name = "Bluetooth", 355 .playback = { 356 .channels_min = 1, 357 .channels_max = 2, 358 .rate_min = 8000, 359 .rate_max = 16000, 360 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), 361 .formats = SNDRV_PCM_FMTBIT_S16_LE, 362 }, 363 .capture = { 364 .channels_min = 1, 365 .channels_max = 2, 366 .rate_min = 8000, 367 .rate_max = 16000, 368 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), 369 .formats = SNDRV_PCM_FMTBIT_S16_LE, 370 }, 371 }, 372 }; 373 374 static const struct snd_soc_component_driver midas_component = { 375 .name = "midas-audio", 376 }; 377 378 SND_SOC_DAILINK_DEFS(wm1811_hifi, 379 DAILINK_COMP_ARRAY(COMP_EMPTY()), 380 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif1")), 381 DAILINK_COMP_ARRAY(COMP_EMPTY())); 382 383 SND_SOC_DAILINK_DEFS(wm1811_voice, 384 DAILINK_COMP_ARRAY(COMP_EMPTY()), 385 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif2")), 386 DAILINK_COMP_ARRAY(COMP_EMPTY())); 387 388 SND_SOC_DAILINK_DEFS(wm1811_bt, 389 DAILINK_COMP_ARRAY(COMP_EMPTY()), 390 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8994-aif3")), 391 DAILINK_COMP_ARRAY(COMP_EMPTY())); 392 393 static struct snd_soc_dai_link midas_dai[] = { 394 { 395 .name = "WM8994 AIF1", 396 .stream_name = "HiFi Primary", 397 .ops = &midas_aif1_ops, 398 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 399 SND_SOC_DAIFMT_CBM_CFM, 400 SND_SOC_DAILINK_REG(wm1811_hifi), 401 }, { 402 .name = "WM1811 Voice", 403 .stream_name = "Voice call", 404 .ignore_suspend = 1, 405 SND_SOC_DAILINK_REG(wm1811_voice), 406 }, { 407 .name = "WM1811 BT", 408 .stream_name = "Bluetooth", 409 .ignore_suspend = 1, 410 SND_SOC_DAILINK_REG(wm1811_bt), 411 }, 412 }; 413 414 static struct snd_soc_card midas_card = { 415 .name = "Midas WM1811", 416 .owner = THIS_MODULE, 417 418 .dai_link = midas_dai, 419 .num_links = ARRAY_SIZE(midas_dai), 420 .controls = midas_controls, 421 .num_controls = ARRAY_SIZE(midas_controls), 422 .dapm_widgets = midas_dapm_widgets, 423 .num_dapm_widgets = ARRAY_SIZE(midas_dapm_widgets), 424 425 .set_bias_level = midas_set_bias_level, 426 .late_probe = midas_late_probe, 427 }; 428 429 static int midas_probe(struct platform_device *pdev) 430 { 431 struct device_node *cpu_dai_node = NULL, *codec_dai_node = NULL; 432 struct device_node *cpu = NULL, *codec = NULL; 433 struct snd_soc_card *card = &midas_card; 434 struct device *dev = &pdev->dev; 435 static struct snd_soc_dai_link *dai_link; 436 struct midas_priv *priv; 437 int ret, i; 438 439 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 440 if (!priv) 441 return -ENOMEM; 442 443 snd_soc_card_set_drvdata(card, priv); 444 card->dev = dev; 445 446 priv->reg_mic_bias = devm_regulator_get(dev, "mic-bias"); 447 if (IS_ERR(priv->reg_mic_bias)) { 448 dev_err(dev, "Failed to get mic bias regulator\n"); 449 return PTR_ERR(priv->reg_mic_bias); 450 } 451 452 priv->reg_submic_bias = devm_regulator_get(dev, "submic-bias"); 453 if (IS_ERR(priv->reg_submic_bias)) { 454 dev_err(dev, "Failed to get submic bias regulator\n"); 455 return PTR_ERR(priv->reg_submic_bias); 456 } 457 458 priv->gpio_fm_sel = devm_gpiod_get_optional(dev, "fm-sel", GPIOD_OUT_HIGH); 459 if (IS_ERR(priv->gpio_fm_sel)) { 460 dev_err(dev, "Failed to get FM selection GPIO\n"); 461 return PTR_ERR(priv->gpio_fm_sel); 462 } 463 464 priv->gpio_lineout_sel = devm_gpiod_get_optional(dev, "lineout-sel", 465 GPIOD_OUT_HIGH); 466 if (IS_ERR(priv->gpio_lineout_sel)) { 467 dev_err(dev, "Failed to get line out selection GPIO\n"); 468 return PTR_ERR(priv->gpio_lineout_sel); 469 } 470 471 ret = snd_soc_of_parse_card_name(card, "model"); 472 if (ret < 0) { 473 dev_err(dev, "Card name is not specified\n"); 474 return ret; 475 } 476 477 ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); 478 if (ret < 0) { 479 /* Backwards compatible way */ 480 ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing"); 481 if (ret < 0) { 482 dev_err(dev, "Audio routing invalid/unspecified\n"); 483 return ret; 484 } 485 } 486 487 cpu = of_get_child_by_name(dev->of_node, "cpu"); 488 if (!cpu) 489 return -EINVAL; 490 491 codec = of_get_child_by_name(dev->of_node, "codec"); 492 if (!codec) { 493 of_node_put(cpu); 494 return -EINVAL; 495 } 496 497 cpu_dai_node = of_parse_phandle(cpu, "sound-dai", 0); 498 of_node_put(cpu); 499 if (!cpu_dai_node) { 500 dev_err(dev, "parsing cpu/sound-dai failed\n"); 501 of_node_put(codec); 502 return -EINVAL; 503 } 504 505 codec_dai_node = of_parse_phandle(codec, "sound-dai", 0); 506 of_node_put(codec); 507 if (!codec_dai_node) { 508 dev_err(dev, "audio-codec property invalid/missing\n"); 509 ret = -EINVAL; 510 goto put_cpu_dai_node; 511 } 512 513 for_each_card_prelinks(card, i, dai_link) { 514 dai_link->codecs->of_node = codec_dai_node; 515 dai_link->cpus->of_node = cpu_dai_node; 516 dai_link->platforms->of_node = cpu_dai_node; 517 } 518 519 ret = devm_snd_soc_register_component(dev, &midas_component, 520 midas_ext_dai, ARRAY_SIZE(midas_ext_dai)); 521 if (ret < 0) { 522 dev_err(dev, "Failed to register component: %d\n", ret); 523 goto put_codec_dai_node; 524 } 525 526 ret = devm_snd_soc_register_card(dev, card); 527 if (ret < 0) { 528 dev_err(dev, "Failed to register card: %d\n", ret); 529 goto put_codec_dai_node; 530 } 531 532 return 0; 533 534 put_codec_dai_node: 535 of_node_put(codec_dai_node); 536 put_cpu_dai_node: 537 of_node_put(cpu_dai_node); 538 return ret; 539 } 540 541 static const struct of_device_id midas_of_match[] = { 542 { .compatible = "samsung,midas-audio" }, 543 { }, 544 }; 545 MODULE_DEVICE_TABLE(of, midas_of_match); 546 547 static struct platform_driver midas_driver = { 548 .driver = { 549 .name = "midas-audio", 550 .of_match_table = midas_of_match, 551 .pm = &snd_soc_pm_ops, 552 }, 553 .probe = midas_probe, 554 }; 555 module_platform_driver(midas_driver); 556 557 MODULE_AUTHOR("Simon Shields <simon@lineageos.org>"); 558 MODULE_DESCRIPTION("ASoC support for Midas"); 559 MODULE_LICENSE("GPL v2"); 560