diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 2f66d5e8cd15..fad76769f153 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -142,7 +142,7 @@ struct snd_soc_dai_ops { * Called by soc_card drivers, normally in their hw_params. */ int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); - int (*of_xlate_tdm_slot_mask)(unsigned int slots, + int (*xlate_tdm_slot_mask)(unsigned int slots, unsigned int *tx_mask, unsigned int *rx_mask); int (*set_tdm_slot)(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 597962ec28fa..338a91642471 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -13,6 +13,7 @@ config SND_SOC_FSL_SPDIF config SND_SOC_FSL_ESAI tristate select REGMAP_MMIO + select SND_SOC_FSL_UTILS config SND_SOC_FSL_UTILS tristate @@ -120,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 diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 0ba37005ab04..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 | \ @@ -581,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, }; 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 "); 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-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 #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/soc-core.c b/sound/soc/soc-core.c index daca4b7de45c..caebd6353112 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3620,14 +3620,14 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); /** - * snd_soc_of_xlate_tdm_slot - generate tx/rx slot mask. + * snd_soc_xlate_tdm_slot - generate tx/rx slot mask. * @slots: Number of slots in use. * @tx_mask: bitmask representing active TX slots. * @rx_mask: bitmask representing active RX slots. * * Generates the TDM tx and rx slot default masks for DAI. */ -static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots, +static int snd_soc_xlate_tdm_slot_mask(unsigned int slots, unsigned int *tx_mask, unsigned int *rx_mask) { @@ -3657,11 +3657,11 @@ static int snd_soc_of_xlate_tdm_slot_mask(unsigned int slots, int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { - if (dai->driver && dai->driver->ops->of_xlate_tdm_slot_mask) - dai->driver->ops->of_xlate_tdm_slot_mask(slots, + if (dai->driver && dai->driver->ops->xlate_tdm_slot_mask) + dai->driver->ops->xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); else - snd_soc_of_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); + snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); if (dai->driver && dai->driver->ops->set_tdm_slot) return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 0a59e2383ef3..3b0fa12dbff7 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -37,7 +37,6 @@ #include #include -#include "tegra_asoc_utils.h" #include "tegra20_ac97.h" #define DRV_NAME "tegra20-ac97" @@ -376,18 +375,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->playback_dma_data.maxburst = 4; - ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); - if (ret) - goto err_clk_put; - - ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data); - if (ret) - goto err_asoc_utils_fini; - ret = clk_prepare_enable(ac97->clk_ac97); if (ret) { dev_err(&pdev->dev, "clk_enable failed: %d\n", ret); - goto err_asoc_utils_fini; + goto err; } ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops); @@ -419,8 +410,6 @@ err_unregister_component: snd_soc_unregister_component(&pdev->dev); err_clk_disable_unprepare: clk_disable_unprepare(ac97->clk_ac97); -err_asoc_utils_fini: - tegra_asoc_utils_fini(&ac97->util_data); err_clk_put: err: snd_soc_set_ac97_ops(NULL); @@ -434,8 +423,6 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev) tegra_pcm_platform_unregister(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - tegra_asoc_utils_fini(&ac97->util_data); - clk_disable_unprepare(ac97->clk_ac97); snd_soc_set_ac97_ops(NULL); diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h index 4acb3aaba29b..0a39d823edcb 100644 --- a/sound/soc/tegra/tegra20_ac97.h +++ b/sound/soc/tegra/tegra20_ac97.h @@ -90,6 +90,5 @@ struct tegra20_ac97 { struct regmap *regmap; int reset_gpio; int sync_gpio; - struct tegra_asoc_utils_data util_data; }; #endif /* __TEGRA20_AC97_H__ */ diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 45b57892b6a5..25a7f8211ecf 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -29,10 +29,13 @@ #include #include +#include "tegra_asoc_utils.h" + #define DRV_NAME "tegra-snd-wm9712" struct tegra_wm9712 { struct platform_device *codec; + struct tegra_asoc_utils_data util_data; }; static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = { @@ -118,15 +121,25 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node; + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); + if (ret) + goto codec_unregister; + + ret = tegra_asoc_utils_set_ac97_rate(&machine->util_data); + if (ret) + goto asoc_utils_fini; + ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - goto codec_unregister; + goto asoc_utils_fini; } return 0; +asoc_utils_fini: + tegra_asoc_utils_fini(&machine->util_data); codec_unregister: platform_device_del(machine->codec); codec_put: @@ -141,6 +154,8 @@ static int tegra_wm9712_driver_remove(struct platform_device *pdev) snd_soc_unregister_card(card); + tegra_asoc_utils_fini(&machine->util_data); + platform_device_unregister(machine->codec); return 0;