diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 15:38:47 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 15:38:47 -0700 |
commit | c70929147a10fa4538886cb23b934b509c4c0e49 (patch) | |
tree | bd7c25f679b271fc81f2cedc7a70ef059586c353 /sound/soc/fsl | |
parent | 4b1779c2cf030c68aefe939d946475e4136c1895 (diff) | |
parent | 69dd89fd2b9406603d218cab8996cfb232d5b8b9 (diff) |
Merge tag 'sound-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"There have been lots of changes in ALSA core, HD-audio and ASoC, also
most of PCI drivers touched by conversions of printks. All these
resulted in a high volume and wide ranged patch sets in this release.
Many changes are fairly trivial, but also lots of nice cleanups and
refactors. There are a few new drivers, most notably, the Intel
Haswell and Baytrail ASoC driver.
Core changes:
- A bit modernization; embed the device struct into snd_card struct,
so that it may be referred from the beginning. A new
snd_card_new() function is introduced for that, and all drivers
have been converted.
- Simplification in the device management code in ALSA core; now
managed by a simple priority list instead
- Converted many kernel messages to use the standard dev_err() & co;
this would be the pretty visible difference, especially for
HD-audio.
HD-audio:
- Conexant codecs use the auto-parser as default now; the old static
code still remains in case of regressions. Some old quirks have
been rewritten with the fixups for auto-parser.
- C-Media codecs also use the auto-parser as default now, too.
- A device struct is assigned to each HD-audio codec, and the
formerly hwdep attributes are accessible over the codec sysfs, too.
hwdep attributes still remain for compatibility.
- Split the PCI-specific stuff for HD-audio controller into a
separate module, ane make a helper module for the generic
controller driver. This is a preliminary change for supporting
Tegra HDMI controller in near future, which slipped from 3.15
merge.
- Device-specific fixes: mute LED support for Lenovo Ideapad, mic LED
fix for HP laptops, more ASUS subwoofer quirks, yet more Dell
laptop headset quirks
- Make the HD-audio codec response a bit more robust
- A few improvements on Realtek ALC282 / 283 about the pop noises
- A couple of Intel HDMI fixes
ASoC:
- Lots of cleanups for enumerations; refactored lots of error prone
original codes to use more modern APIs
- Elimination of the ASoC level wrappers for I2C and SPI moving us
closer to converting to regmap completely and avoiding some
randconfig hassle
- Provide both manually and transparently locked DAPM APIs rather
than a mix of the two fixing some concurrency issues
- Start converting CODEC drivers to use separate bus interface
drivers rather than having them all in one file helping avoid
dependency issues
- DPCM support for Intel Haswell and Bay Trail platforms, lots of
fixes
- Lots of work on improvements for simple-card, DaVinci and the
Renesas rcar drivers.
- New drivers for Analog Devices ADAU1977, TI PCM512x and parts of
the CSR SiRF SoC, TLV320AIC31XXX, Armada 370 DB, Cirrus cs42xx8
- Fixes for the simple-card DAI format DT mess
- DT support for a couple more devices.
- Use of the tdm_slot mapping in a few drivers
Others:
- Support of reset_resume callback for improved S4 in USB-audio
driver; the device with boot quirks have been little tested, which
we need to watch out in this development cycle
- Add PM support for ICE1712 driver (finally!); it's still pretty
partial support, only for M-Audio devices"
* tag 'sound-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (610 commits)
ALSA: ice1712: Add suspend support for M-Audio ICE1712-based cards
ALSA: ice1712: add suspend support for ICE1712 chip
ALSA: hda - Enable beep for ASUS 1015E
ALSA: asihpi: fix some indenting in snd_card_asihpi_pcm_new()
ALSA: hda - add headset mic detect quirks for three Dell laptops
ASoC: tegra: move AC97 clock handling to the machine driver
ASoC: simple-card: Handle many DAI links
ASoC: simple-card: Add DT documentation for multi-DAI links
ASoC: simple-card: dynamically allocate the DAI link and properties
ASoC: imx-ssi: Add .xlate_tdm_slot_mask() support.
ASoC: fsl-esai: Add .xlate_tdm_slot_mask() support.
ASoC: fsl-utils: Add fsl_asoc_xlate_tdm_slot_mask() support.
ASoC: core: remove the 'of_' prefix of of_xlate_tdm_slot_mask.
ASoC: rcar: subnode tidyup for renesas,rsnd.txt
ASoC: Remove name_prefix unset during DAI link init hack
ALSA: hda - Inform the unexpectedly ignored pins by auto-parser
ASoC: rcar: bugfix: it cares about the non-src case
ARM: bockw: fixup SND_SOC_DAIFMT_CBx_CFx flags
ASoC: pcm: Drop incorrect double/extra frees
ASoC: mfld_machine: Fix compile error
...
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/Kconfig | 14 | ||||
-rw-r--r-- | sound/soc/fsl/eukrea-tlv320.c | 108 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 34 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 332 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.h | 48 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 9 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_utils.c | 27 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_utils.h | 4 | ||||
-rw-r--r-- | sound/soc/fsl/imx-pcm-fiq.c | 7 | ||||
-rw-r--r-- | sound/soc/fsl/imx-ssi.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/wm1133-ev1.c | 11 |
11 files changed, 415 insertions, 181 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 07f8f141727d..338a91642471 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,5 +1,6 @@ config SND_SOC_FSL_SAI tristate + select REGMAP_MMIO select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_FSL_SSI @@ -7,9 +8,12 @@ config SND_SOC_FSL_SSI config SND_SOC_FSL_SPDIF tristate + select REGMAP_MMIO config SND_SOC_FSL_ESAI tristate + select REGMAP_MMIO + select SND_SOC_FSL_UTILS config SND_SOC_FSL_UTILS tristate @@ -117,6 +121,7 @@ if SND_IMX_SOC config SND_SOC_IMX_SSI tristate + select SND_SOC_FSL_UTILS config SND_SOC_IMX_PCM_FIQ tristate @@ -168,12 +173,14 @@ config SND_SOC_EUKREA_TLV320 depends on MACH_EUKREA_MBIMX27_BASEBOARD \ || MACH_EUKREA_MBIMXSD25_BASEBOARD \ || MACH_EUKREA_MBIMXSD35_BASEBOARD \ - || MACH_EUKREA_MBIMXSD51_BASEBOARD + || MACH_EUKREA_MBIMXSD51_BASEBOARD \ + || (OF && ARM) depends on I2C - select SND_SOC_TLV320AIC23 - select SND_SOC_IMX_PCM_FIQ + select SND_SOC_TLV320AIC23_I2C select SND_SOC_IMX_AUDMUX select SND_SOC_IMX_SSI + select SND_SOC_FSL_SSI + select SND_SOC_IMX_PCM_DMA help Enable I2S based access to the TLV320AIC23B codec attached to the SSI interface @@ -204,7 +211,6 @@ config SND_SOC_IMX_SPDIF tristate "SoC Audio support for i.MX boards with S/PDIF" select SND_SOC_IMX_PCM_DMA select SND_SOC_FSL_SPDIF - select REGMAP_MMIO help SoC Audio support for i.MX boards with S/PDIF Say Y if you want to add support for SoC audio on an i.MX board with diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 5983740be123..eb093d5b85c4 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -15,8 +15,11 @@ * */ +#include <linux/errno.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <linux/device.h> #include <linux/i2c.h> #include <sound/core.h> @@ -26,6 +29,7 @@ #include "../codecs/tlv320aic23.h" #include "imx-ssi.h" +#include "fsl_ssi.h" #include "imx-audmux.h" #define CODEC_CLOCK 12000000 @@ -41,7 +45,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret) { + /* fsl_ssi lacks the set_fmt ops. */ + if (ret && ret != -ENOTSUPP) { dev_err(cpu_dai->dev, "Failed to set the cpu dai format.\n"); return ret; @@ -63,11 +68,13 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, "Failed to set the codec sysclk.\n"); return ret; } + snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN); - if (ret) { + /* fsl_ssi lacks the set_sysclk ops */ + if (ret && ret != -EINVAL) { dev_err(cpu_dai->dev, "Can't set the IMX_SSP_SYS_CLK CPU system clock.\n"); return ret; @@ -84,14 +91,10 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { .name = "tlv320aic23", .stream_name = "TLV320AIC23", .codec_dai_name = "tlv320aic23-hifi", - .platform_name = "imx-ssi.0", - .codec_name = "tlv320aic23-codec.0-001a", - .cpu_dai_name = "imx-ssi.0", .ops = &eukrea_tlv320_snd_ops, }; static struct snd_soc_card eukrea_tlv320 = { - .name = "cpuimx-audio", .owner = THIS_MODULE, .dai_link = &eukrea_tlv320_dai, .num_links = 1, @@ -101,8 +104,65 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) { int ret; int int_port = 0, ext_port; + struct device_node *np = pdev->dev.of_node; + struct device_node *ssi_np, *codec_np; - if (machine_is_eukrea_cpuimx27()) { + eukrea_tlv320.dev = &pdev->dev; + if (np) { + ret = snd_soc_of_parse_card_name(&eukrea_tlv320, + "eukrea,model"); + if (ret) { + dev_err(&pdev->dev, + "eukrea,model node missing or invalid.\n"); + goto err; + } + + ssi_np = of_parse_phandle(pdev->dev.of_node, + "ssi-controller", 0); + if (!ssi_np) { + dev_err(&pdev->dev, + "ssi-controller missing or invalid.\n"); + ret = -ENODEV; + goto err; + } + + codec_np = of_parse_phandle(ssi_np, "codec-handle", 0); + if (codec_np) + eukrea_tlv320_dai.codec_of_node = codec_np; + else + dev_err(&pdev->dev, "codec-handle node missing or invalid.\n"); + + ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port); + if (ret) { + dev_err(&pdev->dev, + "fsl,mux-int-port node missing or invalid.\n"); + return ret; + } + ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port); + if (ret) { + dev_err(&pdev->dev, + "fsl,mux-ext-port node missing or invalid.\n"); + return ret; + } + + /* + * The port numbering in the hardware manual starts at 1, while + * the audmux API expects it starts at 0. + */ + int_port--; + ext_port--; + + eukrea_tlv320_dai.cpu_of_node = ssi_np; + eukrea_tlv320_dai.platform_of_node = ssi_np; + } else { + eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0"; + eukrea_tlv320_dai.platform_name = "imx-ssi.0"; + eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a"; + eukrea_tlv320.name = "cpuimx-audio"; + } + + if (machine_is_eukrea_cpuimx27() || + of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) { imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, IMX_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_TFSDIR | @@ -119,8 +179,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) ); } else if (machine_is_eukrea_cpuimx25sd() || machine_is_eukrea_cpuimx35sd() || - machine_is_eukrea_cpuimx51sd()) { - ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3; + machine_is_eukrea_cpuimx51sd() || + of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) { + if (!np) + ext_port = machine_is_eukrea_cpuimx25sd() ? + 4 : 3; + imx_audmux_v2_configure_port(int_port, IMX_AUDMUX_V2_PTCR_SYN | IMX_AUDMUX_V2_PTCR_TFSDIR | @@ -134,14 +198,27 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) ); } else { - /* return happy. We might run on a totally different machine */ - return 0; + if (np) { + /* The eukrea,asoc-tlv320 driver was explicitely + * requested (through the device tree). + */ + dev_err(&pdev->dev, + "Missing or invalid audmux DT node.\n"); + return -ENODEV; + } else { + /* Return happy. + * We might run on a totally different machine. + */ + return 0; + } } - eukrea_tlv320.dev = &pdev->dev; ret = snd_soc_register_card(&eukrea_tlv320); +err: if (ret) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + if (np) + of_node_put(ssi_np); return ret; } @@ -153,10 +230,17 @@ static int eukrea_tlv320_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id imx_tlv320_dt_ids[] = { + { .compatible = "eukrea,asoc-tlv320"}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids); + static struct platform_driver eukrea_tlv320_driver = { .driver = { .name = "eukrea_tlv320", .owner = THIS_MODULE, + .of_match_table = imx_tlv320_dt_ids, }, .probe = eukrea_tlv320_probe, .remove = eukrea_tlv320_remove, diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index c84026c99134..c8e5db1414d7 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -18,6 +18,7 @@ #include "fsl_esai.h" #include "imx-pcm.h" +#include "fsl_utils.h" #define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ @@ -431,17 +432,26 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int fsl_esai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + int ret; struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); /* * Some platforms might use the same bit to gate all three or two of * clocks, so keep all clocks open/close at the same time for safety */ - clk_prepare_enable(esai_priv->coreclk); - if (!IS_ERR(esai_priv->extalclk)) - clk_prepare_enable(esai_priv->extalclk); - if (!IS_ERR(esai_priv->fsysclk)) - clk_prepare_enable(esai_priv->fsysclk); + ret = clk_prepare_enable(esai_priv->coreclk); + if (ret) + return ret; + if (!IS_ERR(esai_priv->extalclk)) { + ret = clk_prepare_enable(esai_priv->extalclk); + if (ret) + goto err_extalck; + } + if (!IS_ERR(esai_priv->fsysclk)) { + ret = clk_prepare_enable(esai_priv->fsysclk); + if (ret) + goto err_fsysclk; + } if (!dai->active) { /* Reset Port C */ @@ -463,6 +473,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream, } return 0; + +err_fsysclk: + if (!IS_ERR(esai_priv->extalclk)) + clk_disable_unprepare(esai_priv->extalclk); +err_extalck: + clk_disable_unprepare(esai_priv->coreclk); + + return ret; } static int fsl_esai_hw_params(struct snd_pcm_substream *substream, @@ -564,6 +582,7 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = { .hw_params = fsl_esai_hw_params, .set_sysclk = fsl_esai_set_dai_sysclk, .set_fmt = fsl_esai_set_dai_fmt, + .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask, .set_tdm_slot = fsl_esai_set_dai_tdm_slot, }; @@ -661,7 +680,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) } } -static const struct regmap_config fsl_esai_regmap_config = { +static struct regmap_config fsl_esai_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -687,6 +706,9 @@ static int fsl_esai_probe(struct platform_device *pdev) esai_priv->pdev = pdev; strcpy(esai_priv->name, np->name); + if (of_property_read_bool(np, "big-endian")) + fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; + /* Get the addresses and IRQ */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index cdd3fa830704..c4a423111673 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -15,6 +15,7 @@ #include <linux/dmaengine.h> #include <linux/module.h> #include <linux/of_address.h> +#include <linux/regmap.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/dmaengine_pcm.h> @@ -22,34 +23,6 @@ #include "fsl_sai.h" -static inline u32 sai_readl(struct fsl_sai *sai, - const void __iomem *addr) -{ - u32 val; - - val = __raw_readl(addr); - - if (likely(sai->big_endian_regs)) - val = be32_to_cpu(val); - else - val = le32_to_cpu(val); - rmb(); - - return val; -} - -static inline void sai_writel(struct fsl_sai *sai, - u32 val, void __iomem *addr) -{ - wmb(); - if (likely(sai->big_endian_regs)) - val = cpu_to_be32(val); - else - val = cpu_to_le32(val); - - __raw_writel(val, addr); -} - static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int fsl_dir) { @@ -61,7 +34,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, else reg_cr2 = FSL_SAI_RCR2; - val_cr2 = sai_readl(sai, sai->base + reg_cr2); + regmap_read(sai->regmap, reg_cr2, &val_cr2); + val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; switch (clk_id) { @@ -81,7 +55,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, return -EINVAL; } - sai_writel(sai, val_cr2, sai->base + reg_cr2); + regmap_write(sai->regmap, reg_cr2, val_cr2); return 0; } @@ -89,32 +63,22 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); int ret; if (dir == SND_SOC_CLOCK_IN) return 0; - ret = clk_prepare_enable(sai->clk); - if (ret) - return ret; - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, FSL_FMT_TRANSMITTER); if (ret) { dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); - goto err_clk; + return ret; } ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, FSL_FMT_RECEIVER); - if (ret) { + if (ret) dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); - goto err_clk; - } - -err_clk: - clk_disable_unprepare(sai->clk); return ret; } @@ -133,43 +97,84 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, reg_cr4 = FSL_SAI_RCR4; } - val_cr2 = sai_readl(sai, sai->base + reg_cr2); - val_cr4 = sai_readl(sai, sai->base + reg_cr4); + regmap_read(sai->regmap, reg_cr2, &val_cr2); + regmap_read(sai->regmap, reg_cr4, &val_cr4); if (sai->big_endian_data) val_cr4 &= ~FSL_SAI_CR4_MF; else val_cr4 |= FSL_SAI_CR4_MF; + /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: + /* + * Frame low, 1clk before data, one word length for frame sync, + * frame sync starts one serial clock cycle earlier, + * that is, together with the last bit of the previous + * data word. + */ + val_cr2 &= ~FSL_SAI_CR2_BCP; + val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP; + break; + case SND_SOC_DAIFMT_LEFT_J: + /* + * Frame high, one word length for frame sync, + * frame sync asserts with the first bit of the frame. + */ + val_cr2 &= ~FSL_SAI_CR2_BCP; + val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); + break; + case SND_SOC_DAIFMT_DSP_A: + /* + * Frame high, 1clk before data, one bit for frame sync, + * frame sync starts one serial clock cycle earlier, + * that is, together with the last bit of the previous + * data word. + */ + val_cr2 &= ~FSL_SAI_CR2_BCP; + val_cr4 &= ~FSL_SAI_CR4_FSP; val_cr4 |= FSL_SAI_CR4_FSE; + sai->is_dsp_mode = true; + break; + case SND_SOC_DAIFMT_DSP_B: + /* + * Frame high, one bit for frame sync, + * frame sync asserts with the first bit of the frame. + */ + val_cr2 &= ~FSL_SAI_CR2_BCP; + val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); + sai->is_dsp_mode = true; break; + case SND_SOC_DAIFMT_RIGHT_J: + /* To be done */ default: return -EINVAL; } + /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_IF: - val_cr4 |= FSL_SAI_CR4_FSP; - val_cr2 &= ~FSL_SAI_CR2_BCP; + /* Invert both clocks */ + val_cr2 ^= FSL_SAI_CR2_BCP; + val_cr4 ^= FSL_SAI_CR4_FSP; break; case SND_SOC_DAIFMT_IB_NF: - val_cr4 &= ~FSL_SAI_CR4_FSP; - val_cr2 &= ~FSL_SAI_CR2_BCP; + /* Invert bit clock */ + val_cr2 ^= FSL_SAI_CR2_BCP; break; case SND_SOC_DAIFMT_NB_IF: - val_cr4 |= FSL_SAI_CR4_FSP; - val_cr2 |= FSL_SAI_CR2_BCP; + /* Invert frame clock */ + val_cr4 ^= FSL_SAI_CR4_FSP; break; case SND_SOC_DAIFMT_NB_NF: - val_cr4 &= ~FSL_SAI_CR4_FSP; - val_cr2 |= FSL_SAI_CR2_BCP; + /* Nothing to do for both normal cases */ break; default: return -EINVAL; } + /* DAI clock master masks */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; @@ -179,39 +184,37 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; break; + case SND_SOC_DAIFMT_CBS_CFM: + val_cr2 |= FSL_SAI_CR2_BCD_MSTR; + val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; + val_cr4 |= FSL_SAI_CR4_FSD_MSTR; + break; default: return -EINVAL; } - sai_writel(sai, val_cr2, sai->base + reg_cr2); - sai_writel(sai, val_cr4, sai->base + reg_cr4); + regmap_write(sai->regmap, reg_cr2, val_cr2); + regmap_write(sai->regmap, reg_cr4, val_cr4); return 0; } static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); int ret; - ret = clk_prepare_enable(sai->clk); - if (ret) - return ret; - ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); if (ret) { dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); - goto err_clk; + return ret; } ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); - if (ret) { + if (ret) dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); - goto err_clk; - } - -err_clk: - clk_disable_unprepare(sai->clk); return ret; } @@ -235,16 +238,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, reg_mr = FSL_SAI_RMR; } - val_cr4 = sai_readl(sai, sai->base + reg_cr4); + regmap_read(sai->regmap, reg_cr4, &val_cr4); + regmap_read(sai->regmap, reg_cr4, &val_cr5); + val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; - val_cr5 = sai_readl(sai, sai->base + reg_cr5); val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; - val_cr4 |= FSL_SAI_CR4_SYWD(word_width); + if (!sai->is_dsp_mode) + val_cr4 |= FSL_SAI_CR4_SYWD(word_width); + val_cr5 |= FSL_SAI_CR5_WNW(word_width); val_cr5 |= FSL_SAI_CR5_W0W(word_width); @@ -257,9 +263,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, val_cr4 |= FSL_SAI_CR4_FRSZ(channels); val_mr = ~0UL - ((1 << channels) - 1); - sai_writel(sai, val_cr4, sai->base + reg_cr4); - sai_writel(sai, val_cr5, sai->base + reg_cr5); - sai_writel(sai, val_mr, sai->base + reg_mr); + regmap_write(sai->regmap, reg_cr4, val_cr4); + regmap_write(sai->regmap, reg_cr5, val_cr5); + regmap_write(sai->regmap, reg_mr, val_mr); return 0; } @@ -268,44 +274,42 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3; - - val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2); - val_cr2 &= ~FSL_SAI_CR2_SYNC; - sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2); + u32 tcsr, rcsr; - val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2); - val_cr2 |= FSL_SAI_CR2_SYNC; - sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2); + /* + * The transmitter bit clock and frame sync are to be + * used by both the transmitter and receiver. + */ + regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, + ~FSL_SAI_CR2_SYNC); + regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, + FSL_SAI_CR2_SYNC); - tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); - rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); + regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); + regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tcsr |= FSL_SAI_CSR_FRDE; rcsr &= ~FSL_SAI_CSR_FRDE; - reg_cr3 = FSL_SAI_TCR3; } else { rcsr |= FSL_SAI_CSR_FRDE; tcsr &= ~FSL_SAI_CSR_FRDE; - reg_cr3 = FSL_SAI_RCR3; } - val_cr3 = sai_readl(sai, sai->base + reg_cr3); - + /* + * It is recommended that the transmitter is the last enabled + * and the first disabled. + */ switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: tcsr |= FSL_SAI_CSR_TERE; rcsr |= FSL_SAI_CSR_TERE; - val_cr3 |= FSL_SAI_CR3_TRCE; - sai_writel(sai, val_cr3, sai->base + reg_cr3); - sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); - sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); + regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); + regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); break; - case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -314,11 +318,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, rcsr &= ~FSL_SAI_CSR_TERE; } - val_cr3 &= ~FSL_SAI_CR3_TRCE; - - sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); - sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); - sai_writel(sai, val_cr3, sai->base + reg_cr3); + regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); + regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); break; default: return -EINVAL; @@ -331,16 +332,32 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 reg; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + reg = FSL_SAI_TCR3; + else + reg = FSL_SAI_RCR3; + + regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, + FSL_SAI_CR3_TRCE); - return clk_prepare_enable(sai->clk); + return 0; } static void fsl_sai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 reg; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + reg = FSL_SAI_TCR3; + else + reg = FSL_SAI_RCR3; - clk_disable_unprepare(sai->clk); + regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, + ~FSL_SAI_CR3_TRCE); } static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { @@ -355,18 +372,13 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); - int ret; - ret = clk_prepare_enable(sai->clk); - if (ret) - return ret; - - sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR); - sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR); - sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1); - sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1); - - clk_disable_unprepare(sai->clk); + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); + regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, + FSL_SAI_MAXBURST_TX * 2); + regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, + FSL_SAI_MAXBURST_RX - 1); snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, &sai->dma_params_rx); @@ -397,26 +409,109 @@ static const struct snd_soc_component_driver fsl_component = { .name = "fsl-sai", }; +static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case FSL_SAI_TCSR: + case FSL_SAI_TCR1: + case FSL_SAI_TCR2: + case FSL_SAI_TCR3: + case FSL_SAI_TCR4: + case FSL_SAI_TCR5: + case FSL_SAI_TFR: + case FSL_SAI_TMR: + case FSL_SAI_RCSR: + case FSL_SAI_RCR1: + case FSL_SAI_RCR2: + case FSL_SAI_RCR3: + case FSL_SAI_RCR4: + case FSL_SAI_RCR5: + case FSL_SAI_RDR: + case FSL_SAI_RFR: + case FSL_SAI_RMR: + return true; + default: + return false; + } +} + +static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case FSL_SAI_TFR: + case FSL_SAI_RFR: + case FSL_SAI_TDR: + case FSL_SAI_RDR: + return true; + default: + return false; + } + +} + +static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case FSL_SAI_TCSR: + case FSL_SAI_TCR1: + case FSL_SAI_TCR2: + case FSL_SAI_TCR3: + case FSL_SAI_TCR4: + case FSL_SAI_TCR5: + case FSL_SAI_TDR: + case FSL_SAI_TMR: + case FSL_SAI_RCSR: + case FSL_SAI_RCR1: + case FSL_SAI_RCR2: + case FSL_SAI_RCR3: + case FSL_SAI_RCR4: + case FSL_SAI_RCR5: + case FSL_SAI_RMR: + return true; + default: + return false; + } +} + +static struct regmap_config fsl_sai_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = FSL_SAI_RMR, + .readable_reg = fsl_sai_readable_reg, + .volatile_reg = fsl_sai_volatile_reg, + .writeable_reg = fsl_sai_writeable_reg, +}; + static int fsl_sai_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct fsl_sai *sai; struct resource *res; + void __iomem *base; int ret; sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); if (!sai) return -ENOMEM; + sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); + if (sai->big_endian_regs) + fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; + + sai->big_endian_data = of_property_read_bool(np, "big-endian-data"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sai->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(sai->base)) - return PTR_ERR(sai->base); - - sai->clk = devm_clk_get(&pdev->dev, "sai"); - if (IS_ERR(sai->clk)) { - dev_err(&pdev->dev, "Cannot get SAI's clock\n"); - return PTR_ERR(sai->clk); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + "sai", base, &fsl_sai_regmap_config); + if (IS_ERR(sai->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + return PTR_ERR(sai->regmap); } sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; @@ -424,9 +519,6 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); - sai->big_endian_data = of_property_read_bool(np, "big-endian-data"); - platform_set_drvdata(pdev, sai); ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 41bb62e69361..e432260be598 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -15,31 +15,36 @@ SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) +/* SAI Register Map Register */ +#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ +#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ +#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ +#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ +#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ +#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ +#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ +#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ +#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ +#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ +#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ +#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ +#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ +#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ +#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ +#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ +#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ +#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ + /* SAI Transmit/Recieve Control Register */ -#define FSL_SAI_TCSR 0x00 -#define FSL_SAI_RCSR 0x80 #define FSL_SAI_CSR_TERE BIT(31) #define FSL_SAI_CSR_FWF BIT(17) #define FSL_SAI_CSR_FRIE BIT(8) #define FSL_SAI_CSR_FRDE BIT(0) -/* SAI Transmit Data/FIFO/MASK Register */ -#define FSL_SAI_TDR 0x20 -#define FSL_SAI_TFR 0x40 -#define FSL_SAI_TMR 0x60 - -/* SAI Recieve Data/FIFO/MASK Register */ -#define FSL_SAI_RDR 0xa0 -#define FSL_SAI_RFR 0xc0 -#define FSL_SAI_RMR 0xe0 - /* SAI Transmit and Recieve Configuration 1 Register */ -#define FSL_SAI_TCR1 0x04 -#define FSL_SAI_RCR1 0x84 +#define FSL_SAI_CR1_RFW_MASK 0x1f /* SAI Transmit and Recieve Configuration 2 Register */ -#define FSL_SAI_TCR2 0x08 -#define FSL_SAI_RCR2 0x88 #define FSL_SAI_CR2_SYNC BIT(30) #define FSL_SAI_CR2_MSEL_MASK (0xff << 26) #define FSL_SAI_CR2_MSEL_BUS 0 @@ -50,15 +55,11 @@ #define FSL_SAI_CR2_BCD_MSTR BIT(24) /* SAI Transmit and Recieve Configuration 3 Register */ -#define FSL_SAI_TCR3 0x0c -#define FSL_SAI_RCR3 0x8c #define FSL_SAI_CR3_TRCE BIT(16) #define FSL_SAI_CR3_WDFL(x) (x) #define FSL_SAI_CR3_WDFL_MASK 0x1f /* SAI Transmit and Recieve Configuration 4 Register */ -#define FSL_SAI_TCR4 0x10 -#define FSL_SAI_RCR4 0x90 #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) @@ -69,8 +70,6 @@ #define FSL_SAI_CR4_FSD_MSTR BIT(0) /* SAI Transmit and Recieve Configuration 5 Register */ -#define FSL_SAI_TCR5 0x14 -#define FSL_SAI_RCR5 0x94 #define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24) #define FSL_SAI_CR5_WNW_MASK (0x1f << 24) #define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16) @@ -100,12 +99,11 @@ #define FSL_SAI_MAXBURST_RX 6 struct fsl_sai { - struct clk *clk; - - void __iomem *base; + struct regmap *regmap; bool big_endian_regs; bool big_endian_data; + bool is_dsp_mode; struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 4d075f1abe78..6452ca83d889 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -911,8 +911,8 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai) { struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai); - dai->playback_dma_data = &spdif_private->dma_params_tx; - dai->capture_dma_data = &spdif_private->dma_params_rx; + snd_soc_dai_init_dma_data(dai, &spdif_private->dma_params_tx, + &spdif_private->dma_params_rx); snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls)); @@ -985,7 +985,7 @@ static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) } } -static const struct regmap_config fsl_spdif_regmap_config = { +static struct regmap_config fsl_spdif_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -1105,6 +1105,9 @@ static int fsl_spdif_probe(struct platform_device *pdev) memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); spdif_priv->cpu_dai_drv.name = spdif_priv->name; + if (of_property_read_bool(np, "big-endian")) + fsl_spdif_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; + /* Get the addresses and IRQ */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index b9e42b503a37..2ac7755da876 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c @@ -86,6 +86,33 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, } EXPORT_SYMBOL(fsl_asoc_get_dma_channel); +/** + * fsl_asoc_xlate_tdm_slot_mask - generate TDM slot TX/RX mask. + * + * @slots: Number of slots in use. + * @tx_mask: bitmask representing active TX slots. + * @rx_mask: bitmask representing active RX slots. + * + * This function used to generate the TDM slot TX/RX mask. And the TX/RX + * mask will use a 0 bit for an active slot as default, and the default + * active bits are at the LSB of the mask value. + */ +int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots, + unsigned int *tx_mask, + unsigned int *rx_mask) +{ + if (!slots) + return -EINVAL; + + if (tx_mask) + *tx_mask = ~((1 << slots) - 1); + if (rx_mask) + *rx_mask = ~((1 << slots) - 1); + + return 0; +} +EXPORT_SYMBOL_GPL(fsl_asoc_xlate_tdm_slot_mask); + MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); MODULE_DESCRIPTION("Freescale ASoC utility code"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h index b2951126527c..df535db40313 100644 --- a/sound/soc/fsl/fsl_utils.h +++ b/sound/soc/fsl/fsl_utils.h @@ -22,5 +22,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name, struct snd_soc_dai_link *dai, unsigned int *dma_channel_id, unsigned int *dma_id); - +int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots, + unsigned int *tx_mask, + unsigned int *rx_mask); #endif /* _FSL_UTILS_H */ diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 6553202dd48c..7abf6a079574 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -270,18 +270,17 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) ret = imx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) - goto out; + return ret; } if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = imx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) - goto out; + return ret; } -out: - return ret; + return 0; } static int ssi_irq = 0; diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index df552fa1aa65..ab2fdd76b693 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -50,6 +50,7 @@ #include <linux/platform_data/asoc-imx-ssi.h> #include "imx-ssi.h" +#include "fsl_utils.h" #define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV) @@ -339,6 +340,7 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { .set_fmt = imx_ssi_set_dai_fmt, .set_clkdiv = imx_ssi_set_dai_clkdiv, .set_sysclk = imx_ssi_set_dai_sysclk, + .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask, .set_tdm_slot = imx_ssi_set_dai_tdm_slot, .trigger = imx_ssi_trigger, }; diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c index fce63252bdbb..804749a6c61e 100644 --- a/sound/soc/fsl/wm1133-ev1.c +++ b/sound/soc/fsl/wm1133-ev1.c @@ -214,12 +214,6 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets, - ARRAY_SIZE(wm1133_ev1_widgets)); - - snd_soc_dapm_add_routes(dapm, wm1133_ev1_map, - ARRAY_SIZE(wm1133_ev1_map)); - /* Headphone jack detection */ snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), @@ -257,6 +251,11 @@ static struct snd_soc_card wm1133_ev1 = { .owner = THIS_MODULE, .dai_link = &wm1133_ev1_dai, .num_links = 1, + + .dapm_widgets = wm1133_ev1_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm1133_ev1_widgets), + .dapm_routes = wm1133_ev1_map, + .num_dapm_routes = ARRAY_SIZE(wm1133_ev1_map), }; static struct platform_device *wm1133_ev1_snd_device; |