Current Linux Kernel is using fsi-xxx card driver for SuperH sound card. But the differences between these were only value/strings of setting. In order to reduce duplicate driver, this patch adds fsi-codec.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/sh_fsi.h | 21 +++++++++ sound/soc/sh/Kconfig | 3 + sound/soc/sh/Makefile | 2 + sound/soc/sh/fsi-codec.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 0 deletions(-) create mode 100644 sound/soc/sh/fsi-codec.c
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index b457e87..e61b251 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h @@ -96,4 +96,25 @@ struct fsi_ak4642_info { int id; };
+/* + * for fsi-codec + */ +#define fsi_link_to_info(p) container_of(p, struct fsi_codec_info, snd_link) +#define fsi_card_to_info(p) container_of(p, struct fsi_codec_info, snd_card) +struct fsi_codec_info { + const char *name; + const char *card; + const char *cpu_dai; + const char *codec; + const char *platform; + const char *codec_dai; + unsigned int codec_fmt; + unsigned int cpu_fmt; + unsigned int sysclk; + + /* used in fsi-codec.c */ + struct snd_soc_dai_link snd_link; + struct snd_soc_card snd_card; +}; + #endif /* __SOUND_FSI_H */ diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index d8e06a6..6c406a5 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -46,6 +46,9 @@ config SND_SH7760_AC97 This option enables generic sound support for the first AC97 unit of the SH7760.
+config SND_FSI_CODEC + tristate + config SND_FSI_AK4642 tristate "FSI-AK4642 sound support" depends on SND_SOC_SH4_FSI && I2C diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index 94476d4..82ce3e3 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -17,10 +17,12 @@ snd-soc-sh7760-ac97-objs := sh7760-ac97.o snd-soc-fsi-ak4642-objs := fsi-ak4642.o snd-soc-fsi-da7210-objs := fsi-da7210.o snd-soc-fsi-hdmi-objs := fsi-hdmi.o +snd-soc-fsi-codec-objs := fsi-codec.o snd-soc-migor-objs := migor.o
obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o +obj-$(CONFIG_SND_FSI_CODEC) += snd-soc-fsi-codec.o obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o diff --git a/sound/soc/sh/fsi-codec.c b/sound/soc/sh/fsi-codec.c new file mode 100644 index 0000000..9781106e --- /dev/null +++ b/sound/soc/sh/fsi-codec.c @@ -0,0 +1,106 @@ +/* + * FSI-Codec sound card support + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto kuninori.morimoto.gx@renesas.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/platform_device.h> +#include <linux/module.h> +#include <sound/sh_fsi.h> + +static int fsi_codec_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct fsi_codec_info *pinfo = fsi_link_to_info(rtd->dai_link); + struct snd_soc_dai *codec = rtd->codec_dai; + struct snd_soc_dai *cpu = rtd->cpu_dai; + int ret; + + ret = 0; + if (pinfo->codec_fmt) { + ret = snd_soc_dai_set_fmt(codec, pinfo->codec_fmt); + if (ret < 0) + return ret; + } + + if (pinfo->sysclk) { + ret = snd_soc_dai_set_sysclk(codec, 0, pinfo->sysclk, 0); + if (ret < 0) + return ret; + } + + if (pinfo->cpu_fmt) { + ret = snd_soc_dai_set_fmt(cpu, pinfo->cpu_fmt); + if (ret < 0) + return ret; + } + + return ret; +} + +static int fsi_codec_probe(struct platform_device *pdev) +{ + struct fsi_codec_info *pinfo = pdev->dev.platform_data; + + if (!pinfo) { + dev_err(&pdev->dev, "no info for fsi-codec\n"); + return -EINVAL; + } + + if (!pinfo->name || + !pinfo->card || + !pinfo->cpu_dai || + !pinfo->codec || + !pinfo->platform || + !pinfo->codec_dai) { + dev_err(&pdev->dev, "insufficient fsi_codec_info settings\n"); + return -EINVAL; + } + + /* + * init snd_soc_dai_link + */ + pinfo->snd_link.name = pinfo->name; + pinfo->snd_link.stream_name = pinfo->name; + pinfo->snd_link.cpu_dai_name = pinfo->cpu_dai; + pinfo->snd_link.platform_name = pinfo->platform; + pinfo->snd_link.codec_name = pinfo->codec; + pinfo->snd_link.codec_dai_name = pinfo->codec_dai; + pinfo->snd_link.init = fsi_codec_dai_init; + + /* + * init snd_soc_card + */ + pinfo->snd_card.name = pinfo->card; + pinfo->snd_card.owner = THIS_MODULE; + pinfo->snd_card.dai_link = &pinfo->snd_link; + pinfo->snd_card.num_links = 1; + pinfo->snd_card.dev = &pdev->dev; + + return snd_soc_register_card(&pinfo->snd_card); +} + +static int fsi_codec_remove(struct platform_device *pdev) +{ + struct fsi_codec_info *pinfo = pdev->dev.platform_data; + + return snd_soc_unregister_card(&pinfo->snd_card); +} + +static struct platform_driver fsi_codec = { + .driver = { + .name = "fsi-codec-audio", + }, + .probe = fsi_codec_probe, + .remove = fsi_codec_remove, +}; + +module_platform_driver(fsi_codec); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic SuperH FSI-Codec sound card"); +MODULE_AUTHOR("Kuninori Morimoto kuninori.morimoto.gx@renesas.com");