1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip machine ASoC driver for boards using a MAX90809 CODEC. 4 * 5 * Copyright (c) 2014, ROCKCHIP CORPORATION. All rights reserved. 6 */ 7 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/platform_device.h> 11 #include <linux/slab.h> 12 #include <sound/core.h> 13 #include <sound/jack.h> 14 #include <sound/pcm.h> 15 #include <sound/pcm_params.h> 16 #include <sound/soc.h> 17 18 #include "rockchip_i2s.h" 19 #include "../codecs/ts3a227e.h" 20 21 #define DRV_NAME "rockchip-snd-max98090" 22 23 static struct snd_soc_jack headset_jack; 24 25 /* Headset jack detection DAPM pins */ 26 static struct snd_soc_jack_pin headset_jack_pins[] = { 27 { 28 .pin = "Headphone", 29 .mask = SND_JACK_HEADPHONE, 30 }, 31 { 32 .pin = "Headset Mic", 33 .mask = SND_JACK_MICROPHONE, 34 }, 35 36 }; 37 38 #define RK_MAX98090_WIDGETS \ 39 SND_SOC_DAPM_HP("Headphone", NULL), \ 40 SND_SOC_DAPM_MIC("Headset Mic", NULL), \ 41 SND_SOC_DAPM_MIC("Int Mic", NULL), \ 42 SND_SOC_DAPM_SPK("Speaker", NULL) 43 44 #define RK_HDMI_WIDGETS \ 45 SND_SOC_DAPM_LINE("HDMI", NULL) 46 47 static const struct snd_soc_dapm_widget rk_max98090_dapm_widgets[] = { 48 RK_MAX98090_WIDGETS, 49 }; 50 51 static const struct snd_soc_dapm_widget rk_hdmi_dapm_widgets[] = { 52 RK_HDMI_WIDGETS, 53 }; 54 55 static const struct snd_soc_dapm_widget rk_max98090_hdmi_dapm_widgets[] = { 56 RK_MAX98090_WIDGETS, 57 RK_HDMI_WIDGETS, 58 }; 59 60 #define RK_MAX98090_AUDIO_MAP \ 61 {"IN34", NULL, "Headset Mic"}, \ 62 {"Headset Mic", NULL, "MICBIAS"}, \ 63 {"DMICL", NULL, "Int Mic"}, \ 64 {"Headphone", NULL, "HPL"}, \ 65 {"Headphone", NULL, "HPR"}, \ 66 {"Speaker", NULL, "SPKL"}, \ 67 {"Speaker", NULL, "SPKR"} 68 69 #define RK_HDMI_AUDIO_MAP \ 70 {"HDMI", NULL, "TX"} 71 72 static const struct snd_soc_dapm_route rk_max98090_audio_map[] = { 73 RK_MAX98090_AUDIO_MAP, 74 }; 75 76 static const struct snd_soc_dapm_route rk_hdmi_audio_map[] = { 77 RK_HDMI_AUDIO_MAP, 78 }; 79 80 static const struct snd_soc_dapm_route rk_max98090_hdmi_audio_map[] = { 81 RK_MAX98090_AUDIO_MAP, 82 RK_HDMI_AUDIO_MAP, 83 }; 84 85 #define RK_MAX98090_CONTROLS \ 86 SOC_DAPM_PIN_SWITCH("Headphone"), \ 87 SOC_DAPM_PIN_SWITCH("Headset Mic"), \ 88 SOC_DAPM_PIN_SWITCH("Int Mic"), \ 89 SOC_DAPM_PIN_SWITCH("Speaker") 90 91 #define RK_HDMI_CONTROLS \ 92 SOC_DAPM_PIN_SWITCH("HDMI") 93 94 static const struct snd_kcontrol_new rk_max98090_controls[] = { 95 RK_MAX98090_CONTROLS, 96 }; 97 98 static const struct snd_kcontrol_new rk_hdmi_controls[] = { 99 RK_HDMI_CONTROLS, 100 }; 101 102 static const struct snd_kcontrol_new rk_max98090_hdmi_controls[] = { 103 RK_MAX98090_CONTROLS, 104 RK_HDMI_CONTROLS, 105 }; 106 107 static int rk_jack_event(struct notifier_block *nb, unsigned long event, 108 void *data) 109 { 110 struct snd_soc_jack *jack = (struct snd_soc_jack *)data; 111 struct snd_soc_dapm_context *dapm = &jack->card->dapm; 112 113 if (event & SND_JACK_MICROPHONE) { 114 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); 115 snd_soc_dapm_force_enable_pin(dapm, "SHDN"); 116 } else { 117 snd_soc_dapm_disable_pin(dapm, "MICBIAS"); 118 snd_soc_dapm_disable_pin(dapm, "SHDN"); 119 } 120 121 snd_soc_dapm_sync(dapm); 122 123 return 0; 124 } 125 126 static struct notifier_block rk_jack_nb = { 127 .notifier_call = rk_jack_event, 128 }; 129 130 static int rk_init(struct snd_soc_pcm_runtime *runtime) 131 { 132 /* 133 * The jack has already been created in the rk_98090_headset_init() 134 * function. 135 */ 136 snd_soc_jack_notifier_register(&headset_jack, &rk_jack_nb); 137 138 return 0; 139 } 140 141 static int rk_aif1_hw_params(struct snd_pcm_substream *substream, 142 struct snd_pcm_hw_params *params) 143 { 144 int ret = 0; 145 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 146 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 147 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); 148 int mclk; 149 150 switch (params_rate(params)) { 151 case 8000: 152 case 16000: 153 case 24000: 154 case 32000: 155 case 48000: 156 case 64000: 157 case 96000: 158 mclk = 12288000; 159 break; 160 case 11025: 161 case 22050: 162 case 44100: 163 case 88200: 164 mclk = 11289600; 165 break; 166 default: 167 return -EINVAL; 168 } 169 170 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, 171 SND_SOC_CLOCK_OUT); 172 if (ret) { 173 dev_err(cpu_dai->dev, "Can't set cpu dai clock %d\n", ret); 174 return ret; 175 } 176 177 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 178 SND_SOC_CLOCK_IN); 179 180 /* HDMI codec dai does not need to set sysclk. */ 181 if (!strcmp(rtd->dai_link->name, "HDMI")) 182 return 0; 183 184 if (ret) { 185 dev_err(codec_dai->dev, "Can't set codec dai clock %d\n", ret); 186 return ret; 187 } 188 189 return ret; 190 } 191 192 static int rk_aif1_startup(struct snd_pcm_substream *substream) 193 { 194 /* 195 * Set period size to 240 because pl330 has issue 196 * dealing with larger period in stress testing. 197 */ 198 return snd_pcm_hw_constraint_minmax(substream->runtime, 199 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 240, 240); 200 } 201 202 static const struct snd_soc_ops rk_aif1_ops = { 203 .hw_params = rk_aif1_hw_params, 204 .startup = rk_aif1_startup, 205 }; 206 207 SND_SOC_DAILINK_DEFS(analog, 208 DAILINK_COMP_ARRAY(COMP_EMPTY()), 209 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")), 210 DAILINK_COMP_ARRAY(COMP_EMPTY())); 211 212 SND_SOC_DAILINK_DEFS(hdmi, 213 DAILINK_COMP_ARRAY(COMP_EMPTY()), 214 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), 215 DAILINK_COMP_ARRAY(COMP_EMPTY())); 216 217 enum { 218 DAILINK_MAX98090, 219 DAILINK_HDMI, 220 }; 221 222 static struct snd_soc_jack rk_hdmi_jack; 223 224 static int rk_hdmi_init(struct snd_soc_pcm_runtime *runtime) 225 { 226 struct snd_soc_card *card = runtime->card; 227 struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; 228 int ret; 229 230 /* enable jack detection */ 231 ret = snd_soc_card_jack_new(card, "HDMI Jack", SND_JACK_LINEOUT, 232 &rk_hdmi_jack); 233 if (ret) { 234 dev_err(card->dev, "Can't new HDMI Jack %d\n", ret); 235 return ret; 236 } 237 238 return snd_soc_component_set_jack(component, &rk_hdmi_jack, NULL); 239 } 240 241 /* max98090 dai_link */ 242 static struct snd_soc_dai_link rk_max98090_dailinks[] = { 243 { 244 .name = "max98090", 245 .stream_name = "Analog", 246 .init = rk_init, 247 .ops = &rk_aif1_ops, 248 /* set max98090 as slave */ 249 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 250 SND_SOC_DAIFMT_CBS_CFS, 251 SND_SOC_DAILINK_REG(analog), 252 }, 253 }; 254 255 /* HDMI codec dai_link */ 256 static struct snd_soc_dai_link rk_hdmi_dailinks[] = { 257 { 258 .name = "HDMI", 259 .stream_name = "HDMI", 260 .init = rk_hdmi_init, 261 .ops = &rk_aif1_ops, 262 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 263 SND_SOC_DAIFMT_CBS_CFS, 264 SND_SOC_DAILINK_REG(hdmi), 265 } 266 }; 267 268 /* max98090 and HDMI codec dai_link */ 269 static struct snd_soc_dai_link rk_max98090_hdmi_dailinks[] = { 270 [DAILINK_MAX98090] = { 271 .name = "max98090", 272 .stream_name = "Analog", 273 .init = rk_init, 274 .ops = &rk_aif1_ops, 275 /* set max98090 as slave */ 276 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 277 SND_SOC_DAIFMT_CBS_CFS, 278 SND_SOC_DAILINK_REG(analog), 279 }, 280 [DAILINK_HDMI] = { 281 .name = "HDMI", 282 .stream_name = "HDMI", 283 .init = rk_hdmi_init, 284 .ops = &rk_aif1_ops, 285 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 286 SND_SOC_DAIFMT_CBS_CFS, 287 SND_SOC_DAILINK_REG(hdmi), 288 } 289 }; 290 291 static int rk_98090_headset_init(struct snd_soc_component *component); 292 293 static struct snd_soc_aux_dev rk_98090_headset_dev = { 294 .dlc = COMP_EMPTY(), 295 .init = rk_98090_headset_init, 296 }; 297 298 static struct snd_soc_card rockchip_max98090_card = { 299 .name = "ROCKCHIP-I2S", 300 .owner = THIS_MODULE, 301 .dai_link = rk_max98090_dailinks, 302 .num_links = ARRAY_SIZE(rk_max98090_dailinks), 303 .aux_dev = &rk_98090_headset_dev, 304 .num_aux_devs = 1, 305 .dapm_widgets = rk_max98090_dapm_widgets, 306 .num_dapm_widgets = ARRAY_SIZE(rk_max98090_dapm_widgets), 307 .dapm_routes = rk_max98090_audio_map, 308 .num_dapm_routes = ARRAY_SIZE(rk_max98090_audio_map), 309 .controls = rk_max98090_controls, 310 .num_controls = ARRAY_SIZE(rk_max98090_controls), 311 }; 312 313 static struct snd_soc_card rockchip_hdmi_card = { 314 .name = "ROCKCHIP-HDMI", 315 .owner = THIS_MODULE, 316 .dai_link = rk_hdmi_dailinks, 317 .num_links = ARRAY_SIZE(rk_hdmi_dailinks), 318 .dapm_widgets = rk_hdmi_dapm_widgets, 319 .num_dapm_widgets = ARRAY_SIZE(rk_hdmi_dapm_widgets), 320 .dapm_routes = rk_hdmi_audio_map, 321 .num_dapm_routes = ARRAY_SIZE(rk_hdmi_audio_map), 322 .controls = rk_hdmi_controls, 323 .num_controls = ARRAY_SIZE(rk_hdmi_controls), 324 }; 325 326 static struct snd_soc_card rockchip_max98090_hdmi_card = { 327 .name = "ROCKCHIP-MAX98090-HDMI", 328 .owner = THIS_MODULE, 329 .dai_link = rk_max98090_hdmi_dailinks, 330 .num_links = ARRAY_SIZE(rk_max98090_hdmi_dailinks), 331 .aux_dev = &rk_98090_headset_dev, 332 .num_aux_devs = 1, 333 .dapm_widgets = rk_max98090_hdmi_dapm_widgets, 334 .num_dapm_widgets = ARRAY_SIZE(rk_max98090_hdmi_dapm_widgets), 335 .dapm_routes = rk_max98090_hdmi_audio_map, 336 .num_dapm_routes = ARRAY_SIZE(rk_max98090_hdmi_audio_map), 337 .controls = rk_max98090_hdmi_controls, 338 .num_controls = ARRAY_SIZE(rk_max98090_hdmi_controls), 339 }; 340 341 static int rk_98090_headset_init(struct snd_soc_component *component) 342 { 343 int ret; 344 345 /* Enable Headset and 4 Buttons Jack detection */ 346 ret = snd_soc_card_jack_new_pins(component->card, "Headset Jack", 347 SND_JACK_HEADSET | 348 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 349 SND_JACK_BTN_2 | SND_JACK_BTN_3, 350 &headset_jack, 351 headset_jack_pins, 352 ARRAY_SIZE(headset_jack_pins)); 353 if (ret) 354 return ret; 355 356 ret = ts3a227e_enable_jack_detect(component, &headset_jack); 357 358 return ret; 359 } 360 361 static int rk_parse_headset_from_of(struct device *dev, struct device_node *np) 362 { 363 rk_98090_headset_dev.dlc.of_node = of_parse_phandle( 364 np, "rockchip,headset-codec", 0); 365 if (!rk_98090_headset_dev.dlc.of_node) { 366 dev_err(dev, 367 "Property 'rockchip,headset-codec' missing/invalid\n"); 368 return -EINVAL; 369 } 370 return 0; 371 } 372 373 static int snd_rk_mc_probe(struct platform_device *pdev) 374 { 375 int ret = 0; 376 struct snd_soc_card *card; 377 struct device *dev = &pdev->dev; 378 struct device_node *np = pdev->dev.of_node; 379 struct device_node *np_cpu; 380 struct device_node *np_audio, *np_hdmi; 381 382 /* Parse DTS for I2S controller. */ 383 np_cpu = of_parse_phandle(np, "rockchip,i2s-controller", 0); 384 385 if (!np_cpu) { 386 dev_err(&pdev->dev, 387 "Property 'rockchip,i2s-controller missing or invalid\n"); 388 return -EINVAL; 389 } 390 391 /* 392 * Find the card to use based on the presences of audio codec 393 * and hdmi codec in device property. Set their of_node accordingly. 394 */ 395 np_audio = of_parse_phandle(np, "rockchip,audio-codec", 0); 396 np_hdmi = of_parse_phandle(np, "rockchip,hdmi-codec", 0); 397 if (np_audio && np_hdmi) { 398 card = &rockchip_max98090_hdmi_card; 399 card->dai_link[DAILINK_MAX98090].codecs->of_node = np_audio; 400 card->dai_link[DAILINK_HDMI].codecs->of_node = np_hdmi; 401 card->dai_link[DAILINK_MAX98090].cpus->of_node = np_cpu; 402 card->dai_link[DAILINK_MAX98090].platforms->of_node = np_cpu; 403 card->dai_link[DAILINK_HDMI].cpus->of_node = np_cpu; 404 card->dai_link[DAILINK_HDMI].platforms->of_node = np_cpu; 405 } else if (np_audio) { 406 card = &rockchip_max98090_card; 407 card->dai_link[0].codecs->of_node = np_audio; 408 card->dai_link[0].cpus->of_node = np_cpu; 409 card->dai_link[0].platforms->of_node = np_cpu; 410 } else if (np_hdmi) { 411 card = &rockchip_hdmi_card; 412 card->dai_link[0].codecs->of_node = np_hdmi; 413 card->dai_link[0].cpus->of_node = np_cpu; 414 card->dai_link[0].platforms->of_node = np_cpu; 415 } else { 416 dev_err(dev, "At least one of codecs should be specified\n"); 417 return -EINVAL; 418 } 419 420 card->dev = dev; 421 422 /* Parse headset detection codec. */ 423 if (np_audio) { 424 ret = rk_parse_headset_from_of(dev, np); 425 if (ret) 426 return ret; 427 } 428 429 /* Parse card name. */ 430 ret = snd_soc_of_parse_card_name(card, "rockchip,model"); 431 if (ret) { 432 dev_err(&pdev->dev, 433 "Soc parse card name failed %d\n", ret); 434 return ret; 435 } 436 437 /* register the soc card */ 438 ret = devm_snd_soc_register_card(&pdev->dev, card); 439 if (ret) { 440 dev_err(&pdev->dev, 441 "Soc register card failed %d\n", ret); 442 return ret; 443 } 444 445 return ret; 446 } 447 448 static const struct of_device_id rockchip_max98090_of_match[] = { 449 { .compatible = "rockchip,rockchip-audio-max98090", }, 450 {}, 451 }; 452 453 MODULE_DEVICE_TABLE(of, rockchip_max98090_of_match); 454 455 static struct platform_driver snd_rk_mc_driver = { 456 .probe = snd_rk_mc_probe, 457 .driver = { 458 .name = DRV_NAME, 459 .pm = &snd_soc_pm_ops, 460 .of_match_table = rockchip_max98090_of_match, 461 }, 462 }; 463 464 module_platform_driver(snd_rk_mc_driver); 465 466 MODULE_AUTHOR("jianqun <jay.xu@rock-chips.com>"); 467 MODULE_DESCRIPTION("Rockchip max98090 machine ASoC driver"); 468 MODULE_LICENSE("GPL v2"); 469 MODULE_ALIAS("platform:" DRV_NAME); 470