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