diff options
Diffstat (limited to 'sound/soc/mxs')
| -rw-r--r-- | sound/soc/mxs/Kconfig | 3 | ||||
| -rw-r--r-- | sound/soc/mxs/mxs-pcm.c | 14 | ||||
| -rw-r--r-- | sound/soc/mxs/mxs-pcm.h | 1 | ||||
| -rw-r--r-- | sound/soc/mxs/mxs-saif.c | 61 | ||||
| -rw-r--r-- | sound/soc/mxs/mxs-saif.h | 5 | ||||
| -rw-r--r-- | sound/soc/mxs/mxs-sgtl5000.c | 52 |
6 files changed, 69 insertions, 67 deletions
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index 78d321cbe8b..219235c0221 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig @@ -1,6 +1,7 @@ menuconfig SND_MXS_SOC tristate "SoC Audio for Freescale MXS CPUs" - depends on ARCH_MXS + depends on ARCH_MXS || COMPILE_TEST + depends on COMMON_CLK select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index b16abbbf776..a371b4f91c5 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -36,11 +36,6 @@ static const struct snd_pcm_hardware snd_mxs_hardware = { SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_HALF_DUPLEX, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S20_3LE | - SNDRV_PCM_FMTBIT_S24_LE, - .channels_min = 2, - .channels_max = 2, .period_bytes_min = 32, .period_bytes_max = 8192, .periods_min = 1, @@ -56,16 +51,9 @@ static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { int mxs_pcm_platform_register(struct device *dev) { - return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); } EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); -void mxs_pcm_platform_unregister(struct device *dev) -{ - snd_dmaengine_pcm_unregister(dev); -} -EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); - MODULE_LICENSE("GPL"); diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index bc685b67cac..035ea0436ca 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h @@ -20,6 +20,5 @@ #define _MXS_PCM_H int mxs_pcm_platform_register(struct device *dev); -void mxs_pcm_platform_unregister(struct device *dev); #endif diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 54511c5e6a7..231d7e7b071 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -31,7 +31,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/mach-types.h> #include "mxs-saif.h" @@ -51,9 +50,9 @@ static struct mxs_saif *mxs_saif[2]; * This also means that both SAIFs must operate at the same sample rate. * * We abstract this as each saif has a master, the master could be - * himself or other saifs. In the generic saif driver, saif does not need - * to know the different clkmux. Saif only needs to know who is his master - * and operating his master to generate the proper clock rate for him. + * itself or other saifs. In the generic saif driver, saif does not need + * to know the different clkmux. Saif only needs to know who is its master + * and operating its master to generate the proper clock rate for it. * The master id is provided in mach-specific layer according to different * clkmux setting. */ @@ -77,7 +76,7 @@ static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai, * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK * is provided by other SAIF, we provide a interface here to get its master * from its master_id. - * Note that the master could be himself. + * Note that the master could be itself. */ static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif) { @@ -495,6 +494,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); struct mxs_saif *master_saif; u32 delay; + int ret; master_saif = mxs_saif_get_master(saif); if (!master_saif) @@ -504,23 +504,37 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (saif->state == MXS_SAIF_STATE_RUNNING) + return 0; + dev_dbg(cpu_dai->dev, "start\n"); - clk_enable(master_saif->clk); - if (!master_saif->mclk_in_use) - __raw_writel(BM_SAIF_CTRL_RUN, - master_saif->base + SAIF_CTRL + MXS_SET_ADDR); + ret = clk_enable(master_saif->clk); + if (ret) { + dev_err(saif->dev, "Failed to enable master clock\n"); + return ret; + } /* - * If the saif's master is not himself, we also need to enable + * If the saif's master is not itself, we also need to enable * itself clk for its internal basic logic to work. */ if (saif != master_saif) { - clk_enable(saif->clk); + ret = clk_enable(saif->clk); + if (ret) { + dev_err(saif->dev, "Failed to enable master clock\n"); + clk_disable(master_saif->clk); + return ret; + } + __raw_writel(BM_SAIF_CTRL_RUN, saif->base + SAIF_CTRL + MXS_SET_ADDR); } + if (!master_saif->mclk_in_use) + __raw_writel(BM_SAIF_CTRL_RUN, + master_saif->base + SAIF_CTRL + MXS_SET_ADDR); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* * write data to saif data register to trigger @@ -544,6 +558,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, } master_saif->ongoing = 1; + saif->state = MXS_SAIF_STATE_RUNNING; dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n", __raw_readl(saif->base + SAIF_CTRL), @@ -556,6 +571,9 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (saif->state == MXS_SAIF_STATE_STOPPED) + return 0; + dev_dbg(cpu_dai->dev, "stop\n"); /* wait a while for the current sample to complete */ @@ -576,6 +594,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, } master_saif->ongoing = 0; + saif->state = MXS_SAIF_STATE_STOPPED; break; default: @@ -769,8 +788,8 @@ static int mxs_saif_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "failed to init clocks\n"); } - ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component, - &mxs_saif_dai, 1); + ret = devm_snd_soc_register_component(&pdev->dev, &mxs_saif_component, + &mxs_saif_dai, 1); if (ret) { dev_err(&pdev->dev, "register DAI failed\n"); return ret; @@ -779,23 +798,10 @@ static int mxs_saif_probe(struct platform_device *pdev) ret = mxs_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - goto failed_pdev_alloc; + return ret; } return 0; - -failed_pdev_alloc: - snd_soc_unregister_component(&pdev->dev); - - return ret; -} - -static int mxs_saif_remove(struct platform_device *pdev) -{ - mxs_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_component(&pdev->dev); - - return 0; } static const struct of_device_id mxs_saif_dt_ids[] = { @@ -806,7 +812,6 @@ MODULE_DEVICE_TABLE(of, mxs_saif_dt_ids); static struct platform_driver mxs_saif_driver = { .probe = mxs_saif_probe, - .remove = mxs_saif_remove, .driver = { .name = "mxs-saif", diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h index 53eaa4bf0e2..fbaf7badfdf 100644 --- a/sound/soc/mxs/mxs-saif.h +++ b/sound/soc/mxs/mxs-saif.h @@ -124,6 +124,11 @@ struct mxs_saif { u32 fifo_underrun; u32 fifo_overrun; + + enum { + MXS_SAIF_STATE_STOPPED, + MXS_SAIF_STATE_RUNNING, + } state; }; extern int mxs_saif_put_mclk(unsigned int saif_id); diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 1b134d72f12..61822cc53bd 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -25,7 +25,6 @@ #include <sound/soc.h> #include <sound/jack.h> #include <sound/soc-dapm.h> -#include <asm/mach-types.h> #include "../codecs/sgtl5000.h" #include "mxs-saif.h" @@ -51,18 +50,27 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, } /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */ - if (mclk < 8000000 || mclk > 27000000) + if (mclk < 8000000 || mclk > 27000000) { + dev_err(codec_dai->dev, "Invalid mclk frequency: %u.%03uMHz\n", + mclk / 1000000, mclk / 1000 % 1000); return -EINVAL; + } /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */ ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0); - if (ret) + if (ret) { + dev_err(codec_dai->dev, "Failed to set sysclk to %u.%03uMHz\n", + mclk / 1000000, mclk / 1000 % 1000); return ret; + } /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */ ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0); - if (ret) + if (ret) { + dev_err(cpu_dai->dev, "Failed to set sysclk to %u.%03uMHz\n", + mclk / 1000000, mclk / 1000 % 1000); return ret; + } /* set codec to slave mode */ dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | @@ -70,13 +78,19 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, dai_format); - if (ret) + if (ret) { + dev_err(codec_dai->dev, "Failed to set dai format to %08x\n", + dai_format); return ret; + } /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); - if (ret) + if (ret) { + dev_err(cpu_dai->dev, "Failed to set dai format to %08x\n", + dai_format); return ret; + } return 0; } @@ -91,11 +105,13 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { .stream_name = "HiFi Playback", .codec_dai_name = "sgtl5000", .ops = &mxs_sgtl5000_hifi_ops, + .playback_only = true, }, { .name = "HiFi Rx", .stream_name = "HiFi Capture", .codec_dai_name = "sgtl5000", .ops = &mxs_sgtl5000_hifi_ops, + .capture_only = true, }, }; @@ -106,14 +122,12 @@ static struct snd_soc_card mxs_sgtl5000 = { .num_links = ARRAY_SIZE(mxs_sgtl5000_dai), }; -static int mxs_sgtl5000_probe_dt(struct platform_device *pdev) +static int mxs_sgtl5000_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &mxs_sgtl5000; + int ret, i; struct device_node *np = pdev->dev.of_node; struct device_node *saif_np[2], *codec_np; - int i; - - if (!np) - return 1; /* no device tree */ saif_np[0] = of_parse_phandle(np, "saif-controllers", 0); saif_np[1] = of_parse_phandle(np, "saif-controllers", 1); @@ -136,26 +150,16 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev) of_node_put(saif_np[0]); of_node_put(saif_np[1]); - return 0; -} - -static int mxs_sgtl5000_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &mxs_sgtl5000; - int ret; - - ret = mxs_sgtl5000_probe_dt(pdev); - if (ret < 0) - return ret; - /* * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w). * The Sgtl5000 sysclk is derived from saif0 mclk and it's range * should be >= 8MHz and <= 27M. */ ret = mxs_saif_get_mclk(0, 44100 * 256, 44100); - if (ret) + if (ret) { + dev_err(&pdev->dev, "failed to get mclk\n"); return ret; + } card->dev = &pdev->dev; platform_set_drvdata(pdev, card); |
