diff options
-rw-r--r-- | sound/soc/fsl/Kconfig | 8 | ||||
-rw-r--r-- | sound/soc/fsl/Makefile | 1 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai_wm9712.c | 129 |
3 files changed, 138 insertions, 0 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 1df1f7046e0b..e533dc11bba4 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -219,6 +219,14 @@ config SND_SOC_PHYCORE_AC97 Say Y if you want to add support for SoC audio on Phytec phyCORE and phyCARD boards in AC97 mode +config SND_SOC_FSL_SAI_WM9712 + tristate "SoC Audio support for Freescale SoC's using SAI and WM9712 codec" + select SND_SOC_FSL_SAI + select SND_SOC_WM9712 + help + Say Y or M here if you want to add support for SoC audio on Freescale + SoC using SAI and the WM9712 (or compatible) codec. + config SND_SOC_EUKREA_TLV320 tristate "Eukrea TLV320" depends on ARCH_MXC && I2C diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 6aeb886e3864..43f5da761675 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -60,6 +60,7 @@ snd-soc-imx-mc13783-objs := imx-mc13783.o obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o +obj-$(CONFIG_SND_SOC_FSL_SAI_WM9712) += fsl_sai_wm9712.o obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o diff --git a/sound/soc/fsl/fsl_sai_wm9712.c b/sound/soc/fsl/fsl_sai_wm9712.c new file mode 100644 index 000000000000..c510395649d5 --- /dev/null +++ b/sound/soc/fsl/fsl_sai_wm9712.c @@ -0,0 +1,129 @@ +/* + * fsl_sai_wm9712.c -- SoC audio for Freescale SAI + * + * Copyright 2014 Stefan Agner, Toradex AG <stefan@agner.ch> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/module.h> +#include <sound/soc.h> + +#define DRV_NAME "fsl-sai-ac97-dt-driver" + +static struct snd_soc_dai_link fsl_sai_wm9712_dai = { + .name = "AC97 HiFi", + .stream_name = "AC97 HiFi", + .codec_dai_name = "wm9712-hifi", + .codec_name = "wm9712-codec", +}; + +static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_LINE("LineIn", NULL), + SND_SOC_DAPM_MIC("Mic", NULL), +}; + + +static struct snd_soc_card snd_soc_card_fsl_sai_wm9712 = { + .name = "Colibri VF61 AC97 Audio", + .owner = THIS_MODULE, + .dai_link = &fsl_sai_wm9712_dai, + .num_links = 1, + + .dapm_widgets = tegra_wm9712_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra_wm9712_dapm_widgets), + .fully_routed = true, +}; + +static struct platform_device *codec; + +static int fsl_sai_wm9712_driver_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &snd_soc_card_fsl_sai_wm9712; + int ret; + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + + codec = platform_device_alloc("wm9712-codec", -1); + if (!codec) + return -ENOMEM; + + ret = platform_device_add(codec); + if (ret) + goto codec_put; + + ret = snd_soc_of_parse_card_name(card, "fsl,model"); + if (ret) + goto codec_unregister; + + ret = snd_soc_of_parse_audio_routing(card, "fsl,audio-routing"); + if (ret) + goto codec_unregister; + + fsl_sai_wm9712_dai.cpu_of_node = of_parse_phandle(np, + "fsl,ac97-controller", 0); + if (!fsl_sai_wm9712_dai.cpu_of_node) { + dev_err(&pdev->dev, + "Property 'fsl,ac97-controller' missing or invalid\n"); + ret = -EINVAL; + goto codec_unregister; + } + + fsl_sai_wm9712_dai.platform_of_node = fsl_sai_wm9712_dai.cpu_of_node; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + } + + return ret; + +codec_unregister: + platform_device_del(codec); + +codec_put: + platform_device_put(codec); + return ret; +} + +static int fsl_sai_wm9712_driver_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + platform_device_unregister(codec); + + return 0; +} + +static const struct of_device_id fsl_sai_wm9712_of_match[] = { + { .compatible = "fsl,fsl-sai-audio-wm9712", }, + {}, +}; + +static struct platform_driver fsl_sai_wm9712_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = fsl_sai_wm9712_of_match, + }, + .probe = fsl_sai_wm9712_driver_probe, + .remove = fsl_sai_wm9712_driver_remove, +}; +module_platform_driver(fsl_sai_wm9712_driver); + +/* Module information */ +MODULE_AUTHOR("Stefan Agner <stefan@agner.ch>"); +MODULE_DESCRIPTION("ALSA SoC Freescale SAI+WM9712"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, fsl_sai_wm9712_of_match); |