1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Freescale Generic ASoC Sound Card driver with ASRC 4 // 5 // Copyright (C) 2014 Freescale Semiconductor, Inc. 6 // 7 // Author: Nicolin Chen <nicoleotsuka@gmail.com> 8 9 #include <linux/clk.h> 10 #include <linux/i2c.h> 11 #include <linux/module.h> 12 #include <linux/of_platform.h> 13 #if IS_ENABLED(CONFIG_SND_AC97_CODEC) 14 #include <sound/ac97_codec.h> 15 #endif 16 #include <sound/pcm_params.h> 17 #include <sound/soc.h> 18 #include <sound/jack.h> 19 #include <sound/simple_card_utils.h> 20 21 #include "fsl_esai.h" 22 #include "fsl_sai.h" 23 #include "imx-audmux.h" 24 25 #include "../codecs/sgtl5000.h" 26 #include "../codecs/wm8962.h" 27 #include "../codecs/wm8960.h" 28 29 #define CS427x_SYSCLK_MCLK 0 30 31 #define RX 0 32 #define TX 1 33 34 /* Default DAI format without Master and Slave flag */ 35 #define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) 36 37 /** 38 * struct codec_priv - CODEC private data 39 * @mclk_freq: Clock rate of MCLK 40 * @mclk_id: MCLK (or main clock) id for set_sysclk() 41 * @fll_id: FLL (or secordary clock) id for set_sysclk() 42 * @pll_id: PLL id for set_pll() 43 */ 44 struct codec_priv { 45 unsigned long mclk_freq; 46 u32 mclk_id; 47 u32 fll_id; 48 u32 pll_id; 49 }; 50 51 /** 52 * struct cpu_priv - CPU private data 53 * @sysclk_freq: SYSCLK rates for set_sysclk() 54 * @sysclk_dir: SYSCLK directions for set_sysclk() 55 * @sysclk_id: SYSCLK ids for set_sysclk() 56 * @slot_width: Slot width of each frame 57 * 58 * Note: [1] for tx and [0] for rx 59 */ 60 struct cpu_priv { 61 unsigned long sysclk_freq[2]; 62 u32 sysclk_dir[2]; 63 u32 sysclk_id[2]; 64 u32 slot_width; 65 }; 66 67 /** 68 * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data 69 * @dai_link: DAI link structure including normal one and DPCM link 70 * @hp_jack: Headphone Jack structure 71 * @mic_jack: Microphone Jack structure 72 * @pdev: platform device pointer 73 * @codec_priv: CODEC private data 74 * @cpu_priv: CPU private data 75 * @card: ASoC card structure 76 * @streams: Mask of current active streams 77 * @sample_rate: Current sample rate 78 * @sample_format: Current sample format 79 * @asrc_rate: ASRC sample rate used by Back-Ends 80 * @asrc_format: ASRC sample format used by Back-Ends 81 * @dai_fmt: DAI format between CPU and CODEC 82 * @name: Card name 83 */ 84 85 struct fsl_asoc_card_priv { 86 struct snd_soc_dai_link dai_link[3]; 87 struct asoc_simple_jack hp_jack; 88 struct asoc_simple_jack mic_jack; 89 struct platform_device *pdev; 90 struct codec_priv codec_priv; 91 struct cpu_priv cpu_priv; 92 struct snd_soc_card card; 93 u8 streams; 94 u32 sample_rate; 95 snd_pcm_format_t sample_format; 96 u32 asrc_rate; 97 snd_pcm_format_t asrc_format; 98 u32 dai_fmt; 99 char name[32]; 100 }; 101 102 /* 103 * This dapm route map exists for DPCM link only. 104 * The other routes shall go through Device Tree. 105 * 106 * Note: keep all ASRC routes in the second half 107 * to drop them easily for non-ASRC cases. 108 */ 109 static const struct snd_soc_dapm_route audio_map[] = { 110 /* 1st half -- Normal DAPM routes */ 111 {"Playback", NULL, "CPU-Playback"}, 112 {"CPU-Capture", NULL, "Capture"}, 113 /* 2nd half -- ASRC DAPM routes */ 114 {"CPU-Playback", NULL, "ASRC-Playback"}, 115 {"ASRC-Capture", NULL, "CPU-Capture"}, 116 }; 117 118 static const struct snd_soc_dapm_route audio_map_ac97[] = { 119 /* 1st half -- Normal DAPM routes */ 120 {"Playback", NULL, "AC97 Playback"}, 121 {"AC97 Capture", NULL, "Capture"}, 122 /* 2nd half -- ASRC DAPM routes */ 123 {"AC97 Playback", NULL, "ASRC-Playback"}, 124 {"ASRC-Capture", NULL, "AC97 Capture"}, 125 }; 126 127 static const struct snd_soc_dapm_route audio_map_tx[] = { 128 /* 1st half -- Normal DAPM routes */ 129 {"Playback", NULL, "CPU-Playback"}, 130 /* 2nd half -- ASRC DAPM routes */ 131 {"CPU-Playback", NULL, "ASRC-Playback"}, 132 }; 133 134 /* Add all possible widgets into here without being redundant */ 135 static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = { 136 SND_SOC_DAPM_LINE("Line Out Jack", NULL), 137 SND_SOC_DAPM_LINE("Line In Jack", NULL), 138 SND_SOC_DAPM_HP("Headphone Jack", NULL), 139 SND_SOC_DAPM_SPK("Ext Spk", NULL), 140 SND_SOC_DAPM_MIC("Mic Jack", NULL), 141 SND_SOC_DAPM_MIC("AMIC", NULL), 142 SND_SOC_DAPM_MIC("DMIC", NULL), 143 }; 144 145 static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv) 146 { 147 return priv->dai_fmt == SND_SOC_DAIFMT_AC97; 148 } 149 150 static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, 151 struct snd_pcm_hw_params *params) 152 { 153 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 154 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 155 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 156 struct codec_priv *codec_priv = &priv->codec_priv; 157 struct cpu_priv *cpu_priv = &priv->cpu_priv; 158 struct device *dev = rtd->card->dev; 159 unsigned int pll_out; 160 int ret; 161 162 priv->sample_rate = params_rate(params); 163 priv->sample_format = params_format(params); 164 priv->streams |= BIT(substream->stream); 165 166 if (fsl_asoc_card_is_ac97(priv)) 167 return 0; 168 169 /* Specific configurations of DAIs starts from here */ 170 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), cpu_priv->sysclk_id[tx], 171 cpu_priv->sysclk_freq[tx], 172 cpu_priv->sysclk_dir[tx]); 173 if (ret && ret != -ENOTSUPP) { 174 dev_err(dev, "failed to set sysclk for cpu dai\n"); 175 goto fail; 176 } 177 178 if (cpu_priv->slot_width) { 179 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 180 cpu_priv->slot_width); 181 if (ret && ret != -ENOTSUPP) { 182 dev_err(dev, "failed to set TDM slot for cpu dai\n"); 183 goto fail; 184 } 185 } 186 187 /* Specific configuration for PLL */ 188 if (codec_priv->pll_id && codec_priv->fll_id) { 189 if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE) 190 pll_out = priv->sample_rate * 384; 191 else 192 pll_out = priv->sample_rate * 256; 193 194 ret = snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 195 codec_priv->pll_id, 196 codec_priv->mclk_id, 197 codec_priv->mclk_freq, pll_out); 198 if (ret) { 199 dev_err(dev, "failed to start FLL: %d\n", ret); 200 goto fail; 201 } 202 203 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), 204 codec_priv->fll_id, 205 pll_out, SND_SOC_CLOCK_IN); 206 207 if (ret && ret != -ENOTSUPP) { 208 dev_err(dev, "failed to set SYSCLK: %d\n", ret); 209 goto fail; 210 } 211 } 212 213 return 0; 214 215 fail: 216 priv->streams &= ~BIT(substream->stream); 217 return ret; 218 } 219 220 static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream) 221 { 222 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 224 struct codec_priv *codec_priv = &priv->codec_priv; 225 struct device *dev = rtd->card->dev; 226 int ret; 227 228 priv->streams &= ~BIT(substream->stream); 229 230 if (!priv->streams && codec_priv->pll_id && codec_priv->fll_id) { 231 /* Force freq to be 0 to avoid error message in codec */ 232 ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), 233 codec_priv->mclk_id, 234 0, 235 SND_SOC_CLOCK_IN); 236 if (ret) { 237 dev_err(dev, "failed to switch away from FLL: %d\n", ret); 238 return ret; 239 } 240 241 ret = snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 242 codec_priv->pll_id, 0, 0, 0); 243 if (ret && ret != -ENOTSUPP) { 244 dev_err(dev, "failed to stop FLL: %d\n", ret); 245 return ret; 246 } 247 } 248 249 return 0; 250 } 251 252 static const struct snd_soc_ops fsl_asoc_card_ops = { 253 .hw_params = fsl_asoc_card_hw_params, 254 .hw_free = fsl_asoc_card_hw_free, 255 }; 256 257 static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 258 struct snd_pcm_hw_params *params) 259 { 260 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 261 struct snd_interval *rate; 262 struct snd_mask *mask; 263 264 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 265 rate->max = rate->min = priv->asrc_rate; 266 267 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 268 snd_mask_none(mask); 269 snd_mask_set_format(mask, priv->asrc_format); 270 271 return 0; 272 } 273 274 SND_SOC_DAILINK_DEFS(hifi, 275 DAILINK_COMP_ARRAY(COMP_EMPTY()), 276 DAILINK_COMP_ARRAY(COMP_EMPTY()), 277 DAILINK_COMP_ARRAY(COMP_EMPTY())); 278 279 SND_SOC_DAILINK_DEFS(hifi_fe, 280 DAILINK_COMP_ARRAY(COMP_EMPTY()), 281 DAILINK_COMP_ARRAY(COMP_DUMMY()), 282 DAILINK_COMP_ARRAY(COMP_EMPTY())); 283 284 SND_SOC_DAILINK_DEFS(hifi_be, 285 DAILINK_COMP_ARRAY(COMP_EMPTY()), 286 DAILINK_COMP_ARRAY(COMP_EMPTY()), 287 DAILINK_COMP_ARRAY(COMP_DUMMY())); 288 289 static struct snd_soc_dai_link fsl_asoc_card_dai[] = { 290 /* Default ASoC DAI Link*/ 291 { 292 .name = "HiFi", 293 .stream_name = "HiFi", 294 .ops = &fsl_asoc_card_ops, 295 SND_SOC_DAILINK_REG(hifi), 296 }, 297 /* DPCM Link between Front-End and Back-End (Optional) */ 298 { 299 .name = "HiFi-ASRC-FE", 300 .stream_name = "HiFi-ASRC-FE", 301 .dpcm_playback = 1, 302 .dpcm_capture = 1, 303 .dynamic = 1, 304 SND_SOC_DAILINK_REG(hifi_fe), 305 }, 306 { 307 .name = "HiFi-ASRC-BE", 308 .stream_name = "HiFi-ASRC-BE", 309 .be_hw_params_fixup = be_hw_params_fixup, 310 .ops = &fsl_asoc_card_ops, 311 .dpcm_playback = 1, 312 .dpcm_capture = 1, 313 .no_pcm = 1, 314 SND_SOC_DAILINK_REG(hifi_be), 315 }, 316 }; 317 318 static int fsl_asoc_card_audmux_init(struct device_node *np, 319 struct fsl_asoc_card_priv *priv) 320 { 321 struct device *dev = &priv->pdev->dev; 322 u32 int_ptcr = 0, ext_ptcr = 0; 323 int int_port, ext_port; 324 int ret; 325 326 ret = of_property_read_u32(np, "mux-int-port", &int_port); 327 if (ret) { 328 dev_err(dev, "mux-int-port missing or invalid\n"); 329 return ret; 330 } 331 ret = of_property_read_u32(np, "mux-ext-port", &ext_port); 332 if (ret) { 333 dev_err(dev, "mux-ext-port missing or invalid\n"); 334 return ret; 335 } 336 337 /* 338 * The port numbering in the hardware manual starts at 1, while 339 * the AUDMUX API expects it starts at 0. 340 */ 341 int_port--; 342 ext_port--; 343 344 /* 345 * Use asynchronous mode (6 wires) for all cases except AC97. 346 * If only 4 wires are needed, just set SSI into 347 * synchronous mode and enable 4 PADs in IOMUX. 348 */ 349 switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { 350 case SND_SOC_DAIFMT_CBM_CFM: 351 int_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | ext_port) | 352 IMX_AUDMUX_V2_PTCR_RCSEL(8 | ext_port) | 353 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | 354 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | 355 IMX_AUDMUX_V2_PTCR_RFSDIR | 356 IMX_AUDMUX_V2_PTCR_RCLKDIR | 357 IMX_AUDMUX_V2_PTCR_TFSDIR | 358 IMX_AUDMUX_V2_PTCR_TCLKDIR; 359 break; 360 case SND_SOC_DAIFMT_CBM_CFS: 361 int_ptcr = IMX_AUDMUX_V2_PTCR_RCSEL(8 | ext_port) | 362 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | 363 IMX_AUDMUX_V2_PTCR_RCLKDIR | 364 IMX_AUDMUX_V2_PTCR_TCLKDIR; 365 ext_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | int_port) | 366 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) | 367 IMX_AUDMUX_V2_PTCR_RFSDIR | 368 IMX_AUDMUX_V2_PTCR_TFSDIR; 369 break; 370 case SND_SOC_DAIFMT_CBS_CFM: 371 int_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | ext_port) | 372 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | 373 IMX_AUDMUX_V2_PTCR_RFSDIR | 374 IMX_AUDMUX_V2_PTCR_TFSDIR; 375 ext_ptcr = IMX_AUDMUX_V2_PTCR_RCSEL(8 | int_port) | 376 IMX_AUDMUX_V2_PTCR_TCSEL(int_port) | 377 IMX_AUDMUX_V2_PTCR_RCLKDIR | 378 IMX_AUDMUX_V2_PTCR_TCLKDIR; 379 break; 380 case SND_SOC_DAIFMT_CBS_CFS: 381 ext_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | int_port) | 382 IMX_AUDMUX_V2_PTCR_RCSEL(8 | int_port) | 383 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) | 384 IMX_AUDMUX_V2_PTCR_TCSEL(int_port) | 385 IMX_AUDMUX_V2_PTCR_RFSDIR | 386 IMX_AUDMUX_V2_PTCR_RCLKDIR | 387 IMX_AUDMUX_V2_PTCR_TFSDIR | 388 IMX_AUDMUX_V2_PTCR_TCLKDIR; 389 break; 390 default: 391 if (!fsl_asoc_card_is_ac97(priv)) 392 return -EINVAL; 393 } 394 395 if (fsl_asoc_card_is_ac97(priv)) { 396 int_ptcr = IMX_AUDMUX_V2_PTCR_SYN | 397 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | 398 IMX_AUDMUX_V2_PTCR_TCLKDIR; 399 ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN | 400 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) | 401 IMX_AUDMUX_V2_PTCR_TFSDIR; 402 } 403 404 /* Asynchronous mode can not be set along with RCLKDIR */ 405 if (!fsl_asoc_card_is_ac97(priv)) { 406 unsigned int pdcr = 407 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port); 408 409 ret = imx_audmux_v2_configure_port(int_port, 0, 410 pdcr); 411 if (ret) { 412 dev_err(dev, "audmux internal port setup failed\n"); 413 return ret; 414 } 415 } 416 417 ret = imx_audmux_v2_configure_port(int_port, int_ptcr, 418 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); 419 if (ret) { 420 dev_err(dev, "audmux internal port setup failed\n"); 421 return ret; 422 } 423 424 if (!fsl_asoc_card_is_ac97(priv)) { 425 unsigned int pdcr = 426 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port); 427 428 ret = imx_audmux_v2_configure_port(ext_port, 0, 429 pdcr); 430 if (ret) { 431 dev_err(dev, "audmux external port setup failed\n"); 432 return ret; 433 } 434 } 435 436 ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr, 437 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 438 if (ret) { 439 dev_err(dev, "audmux external port setup failed\n"); 440 return ret; 441 } 442 443 return 0; 444 } 445 446 static int hp_jack_event(struct notifier_block *nb, unsigned long event, 447 void *data) 448 { 449 struct snd_soc_jack *jack = (struct snd_soc_jack *)data; 450 struct snd_soc_dapm_context *dapm = &jack->card->dapm; 451 452 if (event & SND_JACK_HEADPHONE) 453 /* Disable speaker if headphone is plugged in */ 454 snd_soc_dapm_disable_pin(dapm, "Ext Spk"); 455 else 456 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 457 458 return 0; 459 } 460 461 static struct notifier_block hp_jack_nb = { 462 .notifier_call = hp_jack_event, 463 }; 464 465 static int mic_jack_event(struct notifier_block *nb, unsigned long event, 466 void *data) 467 { 468 struct snd_soc_jack *jack = (struct snd_soc_jack *)data; 469 struct snd_soc_dapm_context *dapm = &jack->card->dapm; 470 471 if (event & SND_JACK_MICROPHONE) 472 /* Disable dmic if microphone is plugged in */ 473 snd_soc_dapm_disable_pin(dapm, "DMIC"); 474 else 475 snd_soc_dapm_enable_pin(dapm, "DMIC"); 476 477 return 0; 478 } 479 480 static struct notifier_block mic_jack_nb = { 481 .notifier_call = mic_jack_event, 482 }; 483 484 static int fsl_asoc_card_late_probe(struct snd_soc_card *card) 485 { 486 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 487 struct snd_soc_pcm_runtime *rtd = list_first_entry( 488 &card->rtd_list, struct snd_soc_pcm_runtime, list); 489 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 490 struct codec_priv *codec_priv = &priv->codec_priv; 491 struct device *dev = card->dev; 492 int ret; 493 494 if (fsl_asoc_card_is_ac97(priv)) { 495 #if IS_ENABLED(CONFIG_SND_AC97_CODEC) 496 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 497 struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component); 498 499 /* 500 * Use slots 3/4 for S/PDIF so SSI won't try to enable 501 * other slots and send some samples there 502 * due to SLOTREQ bits for S/PDIF received from codec 503 */ 504 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, 505 AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4); 506 #endif 507 508 return 0; 509 } 510 511 ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, 512 codec_priv->mclk_freq, SND_SOC_CLOCK_IN); 513 if (ret && ret != -ENOTSUPP) { 514 dev_err(dev, "failed to set sysclk in %s\n", __func__); 515 return ret; 516 } 517 518 return 0; 519 } 520 521 static int fsl_asoc_card_probe(struct platform_device *pdev) 522 { 523 struct device_node *cpu_np, *codec_np, *asrc_np; 524 struct device_node *np = pdev->dev.of_node; 525 struct platform_device *asrc_pdev = NULL; 526 struct device_node *bitclkmaster = NULL; 527 struct device_node *framemaster = NULL; 528 struct platform_device *cpu_pdev; 529 struct fsl_asoc_card_priv *priv; 530 struct device *codec_dev = NULL; 531 const char *codec_dai_name; 532 const char *codec_dev_name; 533 unsigned int daifmt; 534 u32 width; 535 int ret; 536 537 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 538 if (!priv) 539 return -ENOMEM; 540 541 cpu_np = of_parse_phandle(np, "audio-cpu", 0); 542 /* Give a chance to old DT binding */ 543 if (!cpu_np) 544 cpu_np = of_parse_phandle(np, "ssi-controller", 0); 545 if (!cpu_np) { 546 dev_err(&pdev->dev, "CPU phandle missing or invalid\n"); 547 ret = -EINVAL; 548 goto fail; 549 } 550 551 cpu_pdev = of_find_device_by_node(cpu_np); 552 if (!cpu_pdev) { 553 dev_err(&pdev->dev, "failed to find CPU DAI device\n"); 554 ret = -EINVAL; 555 goto fail; 556 } 557 558 codec_np = of_parse_phandle(np, "audio-codec", 0); 559 if (codec_np) { 560 struct platform_device *codec_pdev; 561 struct i2c_client *codec_i2c; 562 563 codec_i2c = of_find_i2c_device_by_node(codec_np); 564 if (codec_i2c) { 565 codec_dev = &codec_i2c->dev; 566 codec_dev_name = codec_i2c->name; 567 } 568 if (!codec_dev) { 569 codec_pdev = of_find_device_by_node(codec_np); 570 if (codec_pdev) { 571 codec_dev = &codec_pdev->dev; 572 codec_dev_name = codec_pdev->name; 573 } 574 } 575 } 576 577 asrc_np = of_parse_phandle(np, "audio-asrc", 0); 578 if (asrc_np) 579 asrc_pdev = of_find_device_by_node(asrc_np); 580 581 /* Get the MCLK rate only, and leave it controlled by CODEC drivers */ 582 if (codec_dev) { 583 struct clk *codec_clk = clk_get(codec_dev, NULL); 584 585 if (!IS_ERR(codec_clk)) { 586 priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); 587 clk_put(codec_clk); 588 } 589 } 590 591 /* Default sample rate and format, will be updated in hw_params() */ 592 priv->sample_rate = 44100; 593 priv->sample_format = SNDRV_PCM_FORMAT_S16_LE; 594 595 /* Assign a default DAI format, and allow each card to overwrite it */ 596 priv->dai_fmt = DAI_FMT_BASE; 597 598 memcpy(priv->dai_link, fsl_asoc_card_dai, 599 sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); 600 601 priv->card.dapm_routes = audio_map; 602 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); 603 /* Diversify the card configurations */ 604 if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) { 605 codec_dai_name = "cs42888"; 606 priv->cpu_priv.sysclk_freq[TX] = priv->codec_priv.mclk_freq; 607 priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq; 608 priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT; 609 priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT; 610 priv->cpu_priv.slot_width = 32; 611 priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; 612 } else if (of_device_is_compatible(np, "fsl,imx-audio-cs427x")) { 613 codec_dai_name = "cs4271-hifi"; 614 priv->codec_priv.mclk_id = CS427x_SYSCLK_MCLK; 615 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 616 } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) { 617 codec_dai_name = "sgtl5000"; 618 priv->codec_priv.mclk_id = SGTL5000_SYSCLK; 619 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 620 } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) { 621 codec_dai_name = "wm8962"; 622 priv->codec_priv.mclk_id = WM8962_SYSCLK_MCLK; 623 priv->codec_priv.fll_id = WM8962_SYSCLK_FLL; 624 priv->codec_priv.pll_id = WM8962_FLL; 625 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 626 } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8960")) { 627 codec_dai_name = "wm8960-hifi"; 628 priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO; 629 priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO; 630 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 631 } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) { 632 codec_dai_name = "ac97-hifi"; 633 priv->dai_fmt = SND_SOC_DAIFMT_AC97; 634 priv->card.dapm_routes = audio_map_ac97; 635 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97); 636 } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) { 637 codec_dai_name = "fsl-mqs-dai"; 638 priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J | 639 SND_SOC_DAIFMT_CBS_CFS | 640 SND_SOC_DAIFMT_NB_NF; 641 priv->dai_link[1].dpcm_capture = 0; 642 priv->dai_link[2].dpcm_capture = 0; 643 priv->card.dapm_routes = audio_map_tx; 644 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx); 645 } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8524")) { 646 codec_dai_name = "wm8524-hifi"; 647 priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; 648 priv->dai_link[1].dpcm_capture = 0; 649 priv->dai_link[2].dpcm_capture = 0; 650 priv->cpu_priv.slot_width = 32; 651 priv->card.dapm_routes = audio_map_tx; 652 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx); 653 } else { 654 dev_err(&pdev->dev, "unknown Device Tree compatible\n"); 655 ret = -EINVAL; 656 goto asrc_fail; 657 } 658 659 /* Format info from DT is optional. */ 660 daifmt = snd_soc_of_parse_daifmt(np, NULL, 661 &bitclkmaster, &framemaster); 662 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; 663 if (bitclkmaster || framemaster) { 664 if (codec_np == bitclkmaster) 665 daifmt |= (codec_np == framemaster) ? 666 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; 667 else 668 daifmt |= (codec_np == framemaster) ? 669 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; 670 671 /* Override dai_fmt with value from DT */ 672 priv->dai_fmt = daifmt; 673 } 674 675 /* Change direction according to format */ 676 if (priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) { 677 priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_IN; 678 priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_IN; 679 } 680 681 of_node_put(bitclkmaster); 682 of_node_put(framemaster); 683 684 if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) { 685 dev_err(&pdev->dev, "failed to find codec device\n"); 686 ret = -EPROBE_DEFER; 687 goto asrc_fail; 688 } 689 690 /* Common settings for corresponding Freescale CPU DAI driver */ 691 if (of_node_name_eq(cpu_np, "ssi")) { 692 /* Only SSI needs to configure AUDMUX */ 693 ret = fsl_asoc_card_audmux_init(np, priv); 694 if (ret) { 695 dev_err(&pdev->dev, "failed to init audmux\n"); 696 goto asrc_fail; 697 } 698 } else if (of_node_name_eq(cpu_np, "esai")) { 699 priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL; 700 priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL; 701 } else if (of_node_name_eq(cpu_np, "sai")) { 702 priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1; 703 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; 704 } 705 706 /* Initialize sound card */ 707 priv->pdev = pdev; 708 priv->card.dev = &pdev->dev; 709 ret = snd_soc_of_parse_card_name(&priv->card, "model"); 710 if (ret) { 711 snprintf(priv->name, sizeof(priv->name), "%s-audio", 712 fsl_asoc_card_is_ac97(priv) ? "ac97" : codec_dev_name); 713 priv->card.name = priv->name; 714 } 715 priv->card.dai_link = priv->dai_link; 716 priv->card.late_probe = fsl_asoc_card_late_probe; 717 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets; 718 priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets); 719 720 /* Drop the second half of DAPM routes -- ASRC */ 721 if (!asrc_pdev) 722 priv->card.num_dapm_routes /= 2; 723 724 if (of_property_read_bool(np, "audio-routing")) { 725 ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing"); 726 if (ret) { 727 dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret); 728 goto asrc_fail; 729 } 730 } 731 732 /* Normal DAI Link */ 733 priv->dai_link[0].cpus->of_node = cpu_np; 734 priv->dai_link[0].codecs->dai_name = codec_dai_name; 735 736 if (!fsl_asoc_card_is_ac97(priv)) 737 priv->dai_link[0].codecs->of_node = codec_np; 738 else { 739 u32 idx; 740 741 ret = of_property_read_u32(cpu_np, "cell-index", &idx); 742 if (ret) { 743 dev_err(&pdev->dev, 744 "cannot get CPU index property\n"); 745 goto asrc_fail; 746 } 747 748 priv->dai_link[0].codecs->name = 749 devm_kasprintf(&pdev->dev, GFP_KERNEL, 750 "ac97-codec.%u", 751 (unsigned int)idx); 752 if (!priv->dai_link[0].codecs->name) { 753 ret = -ENOMEM; 754 goto asrc_fail; 755 } 756 } 757 758 priv->dai_link[0].platforms->of_node = cpu_np; 759 priv->dai_link[0].dai_fmt = priv->dai_fmt; 760 priv->card.num_links = 1; 761 762 if (asrc_pdev) { 763 /* DPCM DAI Links only if ASRC exsits */ 764 priv->dai_link[1].cpus->of_node = asrc_np; 765 priv->dai_link[1].platforms->of_node = asrc_np; 766 priv->dai_link[2].codecs->dai_name = codec_dai_name; 767 priv->dai_link[2].codecs->of_node = codec_np; 768 priv->dai_link[2].codecs->name = 769 priv->dai_link[0].codecs->name; 770 priv->dai_link[2].cpus->of_node = cpu_np; 771 priv->dai_link[2].dai_fmt = priv->dai_fmt; 772 priv->card.num_links = 3; 773 774 ret = of_property_read_u32(asrc_np, "fsl,asrc-rate", 775 &priv->asrc_rate); 776 if (ret) { 777 dev_err(&pdev->dev, "failed to get output rate\n"); 778 ret = -EINVAL; 779 goto asrc_fail; 780 } 781 782 ret = of_property_read_u32(asrc_np, "fsl,asrc-format", 783 &priv->asrc_format); 784 if (ret) { 785 /* Fallback to old binding; translate to asrc_format */ 786 ret = of_property_read_u32(asrc_np, "fsl,asrc-width", 787 &width); 788 if (ret) { 789 dev_err(&pdev->dev, 790 "failed to decide output format\n"); 791 goto asrc_fail; 792 } 793 794 if (width == 24) 795 priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; 796 else 797 priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; 798 } 799 } 800 801 /* Finish card registering */ 802 platform_set_drvdata(pdev, priv); 803 snd_soc_card_set_drvdata(&priv->card, priv); 804 805 ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); 806 if (ret) { 807 if (ret != -EPROBE_DEFER) 808 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 809 goto asrc_fail; 810 } 811 812 /* 813 * Properties "hp-det-gpio" and "mic-det-gpio" are optional, and 814 * asoc_simple_init_jack uses these properties for creating 815 * Headphone Jack and Microphone Jack. 816 * 817 * The notifier is initialized in snd_soc_card_jack_new(), then 818 * snd_soc_jack_notifier_register can be called. 819 */ 820 if (of_property_read_bool(np, "hp-det-gpio")) { 821 ret = asoc_simple_init_jack(&priv->card, &priv->hp_jack, 822 1, NULL, "Headphone Jack"); 823 if (ret) 824 goto asrc_fail; 825 826 snd_soc_jack_notifier_register(&priv->hp_jack.jack, &hp_jack_nb); 827 } 828 829 if (of_property_read_bool(np, "mic-det-gpio")) { 830 ret = asoc_simple_init_jack(&priv->card, &priv->mic_jack, 831 0, NULL, "Mic Jack"); 832 if (ret) 833 goto asrc_fail; 834 835 snd_soc_jack_notifier_register(&priv->mic_jack.jack, &mic_jack_nb); 836 } 837 838 asrc_fail: 839 of_node_put(asrc_np); 840 of_node_put(codec_np); 841 put_device(&cpu_pdev->dev); 842 fail: 843 of_node_put(cpu_np); 844 845 return ret; 846 } 847 848 static const struct of_device_id fsl_asoc_card_dt_ids[] = { 849 { .compatible = "fsl,imx-audio-ac97", }, 850 { .compatible = "fsl,imx-audio-cs42888", }, 851 { .compatible = "fsl,imx-audio-cs427x", }, 852 { .compatible = "fsl,imx-audio-sgtl5000", }, 853 { .compatible = "fsl,imx-audio-wm8962", }, 854 { .compatible = "fsl,imx-audio-wm8960", }, 855 { .compatible = "fsl,imx-audio-mqs", }, 856 { .compatible = "fsl,imx-audio-wm8524", }, 857 {} 858 }; 859 MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids); 860 861 static struct platform_driver fsl_asoc_card_driver = { 862 .probe = fsl_asoc_card_probe, 863 .driver = { 864 .name = "fsl-asoc-card", 865 .pm = &snd_soc_pm_ops, 866 .of_match_table = fsl_asoc_card_dt_ids, 867 }, 868 }; 869 module_platform_driver(fsl_asoc_card_driver); 870 871 MODULE_DESCRIPTION("Freescale Generic ASoC Sound Card driver with ASRC"); 872 MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>"); 873 MODULE_ALIAS("platform:fsl-asoc-card"); 874 MODULE_LICENSE("GPL"); 875