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