diff options
Diffstat (limited to 'sound/soc/fsl/fsl_esai.c')
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index d0c72ed261e7..0ba37005ab04 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | 326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, |
327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | 327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); |
328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | 328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, |
329 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); | 329 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); |
330 | 330 | ||
331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | 334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, |
335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | 335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); |
336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | 336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, |
337 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); | 337 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
338 | 338 | ||
339 | esai_priv->slot_width = slot_width; | 339 | esai_priv->slot_width = slot_width; |
340 | 340 | ||
@@ -431,17 +431,26 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
431 | static int fsl_esai_startup(struct snd_pcm_substream *substream, | 431 | static int fsl_esai_startup(struct snd_pcm_substream *substream, |
432 | struct snd_soc_dai *dai) | 432 | struct snd_soc_dai *dai) |
433 | { | 433 | { |
434 | int ret; | ||
434 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 435 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
435 | 436 | ||
436 | /* | 437 | /* |
437 | * Some platforms might use the same bit to gate all three or two of | 438 | * Some platforms might use the same bit to gate all three or two of |
438 | * clocks, so keep all clocks open/close at the same time for safety | 439 | * clocks, so keep all clocks open/close at the same time for safety |
439 | */ | 440 | */ |
440 | clk_prepare_enable(esai_priv->coreclk); | 441 | ret = clk_prepare_enable(esai_priv->coreclk); |
441 | if (!IS_ERR(esai_priv->extalclk)) | 442 | if (ret) |
442 | clk_prepare_enable(esai_priv->extalclk); | 443 | return ret; |
443 | if (!IS_ERR(esai_priv->fsysclk)) | 444 | if (!IS_ERR(esai_priv->extalclk)) { |
444 | clk_prepare_enable(esai_priv->fsysclk); | 445 | ret = clk_prepare_enable(esai_priv->extalclk); |
446 | if (ret) | ||
447 | goto err_extalck; | ||
448 | } | ||
449 | if (!IS_ERR(esai_priv->fsysclk)) { | ||
450 | ret = clk_prepare_enable(esai_priv->fsysclk); | ||
451 | if (ret) | ||
452 | goto err_fsysclk; | ||
453 | } | ||
445 | 454 | ||
446 | if (!dai->active) { | 455 | if (!dai->active) { |
447 | /* Reset Port C */ | 456 | /* Reset Port C */ |
@@ -463,6 +472,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream, | |||
463 | } | 472 | } |
464 | 473 | ||
465 | return 0; | 474 | return 0; |
475 | |||
476 | err_fsysclk: | ||
477 | if (!IS_ERR(esai_priv->extalclk)) | ||
478 | clk_disable_unprepare(esai_priv->extalclk); | ||
479 | err_extalck: | ||
480 | clk_disable_unprepare(esai_priv->coreclk); | ||
481 | |||
482 | return ret; | ||
466 | } | 483 | } |
467 | 484 | ||
468 | static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | 485 | static int fsl_esai_hw_params(struct snd_pcm_substream *substream, |
@@ -661,7 +678,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) | |||
661 | } | 678 | } |
662 | } | 679 | } |
663 | 680 | ||
664 | static const struct regmap_config fsl_esai_regmap_config = { | 681 | static struct regmap_config fsl_esai_regmap_config = { |
665 | .reg_bits = 32, | 682 | .reg_bits = 32, |
666 | .reg_stride = 4, | 683 | .reg_stride = 4, |
667 | .val_bits = 32, | 684 | .val_bits = 32, |
@@ -687,6 +704,9 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
687 | esai_priv->pdev = pdev; | 704 | esai_priv->pdev = pdev; |
688 | strcpy(esai_priv->name, np->name); | 705 | strcpy(esai_priv->name, np->name); |
689 | 706 | ||
707 | if (of_property_read_bool(np, "big-endian")) | ||
708 | fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; | ||
709 | |||
690 | /* Get the addresses and IRQ */ | 710 | /* Get the addresses and IRQ */ |
691 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 711 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
692 | regs = devm_ioremap_resource(&pdev->dev, res); | 712 | regs = devm_ioremap_resource(&pdev->dev, res); |