Skip to content

Instantly share code, notes, and snippets.

@Simon-L
Created February 20, 2017 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Simon-L/c8c119c86d7d3fe4316387c3ae818379 to your computer and use it in GitHub Desktop.
Save Simon-L/c8c119c86d7d3fe4316387c3ae818379 to your computer and use it in GitHub Desktop.
PCM5102a patches for Armbian on nanopiair
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 7a974e5..3176ced 100755
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -474,3 +474,10 @@ config SND_SOC_TAS5731_CODEC
default n
help
Say Y or M if you want to add support for tas5731.
+
+config SND_SOC_PCM5102A
+ tristate "PCM5102A codec"
+ depends on ARCH_SUN8IW7
+ default n
+ help
+ Say Y or M if you want to add support for pcm5102a codec.
\ No newline at end of file
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1ea3ebc..215d458 100755
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -215,3 +215,5 @@ obj-$(CONFIG_SND_SOC_ACX00DAPM_CODEC) += ac100_dapm.o #AC200
obj-$(CONFIG_SND_SOC_ACX00DAPM_CODEC) += acx00_dapm.o
#tas5731
obj-$(CONFIG_SND_SOC_TAS5731_CODEC) += tas5731.o
+
+obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
\ No newline at end of file
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
new file mode 100644
index 0000000..908b73b
--- /dev/null
+++ b/sound/soc/codecs/pcm5102a.c
@@ -0,0 +1,93 @@
+/*
+ * Driver for the PCM5102A codec
+ *
+ * Author: Florian Meier <florian.meier@koalo.de>
+ * Copyright 2013
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_dai_driver pcm5102a_dai = {
+ .name = "pcm5102a-hifi",
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE
+ },
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
+
+static int pcm5102a_probe(struct platform_device *pdev)
+{
+ printk("%s\n", __func__);
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
+ &pcm5102a_dai, 1);
+}
+
+static int pcm5102a_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id pcm5102a_of_match[] = {
+ { .compatible = "sunxi,pcm5102a", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
+
+static struct platform_driver pcm5102a_codec_driver = {
+ .probe = pcm5102a_probe,
+ .remove = pcm5102a_remove,
+ .driver = {
+ .name = "pcm5102a-codec",
+ .of_match_table = pcm5102a_of_match,
+ },
+};
+
+static struct platform_device pcm5102a_codec_device = {
+ .name = "pcm5102a-codec",
+ .id = PLATFORM_DEVID_NONE,
+};
+
+static int __init pcm5102a_init(void)
+{
+ int err = 0;
+
+ if((err = platform_device_register(&pcm5102a_codec_device)) < 0)
+ return err;
+
+ if ((err = platform_driver_register(&pcm5102a_codec_driver)) < 0)
+ return err;
+
+ return 0;
+}
+module_init(pcm5102a_init);
+
+static void __exit pcm5102a_exit(void)
+{
+ platform_driver_unregister(&pcm5102a_codec_driver);
+ platform_device_unregister(&pcm5102a_codec_device);
+}
+module_exit(pcm5102a_exit);
+
+MODULE_DESCRIPTION("ASoC PCM5102A codec driver");
+MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sunxi/daudio0/Kconfig b/sound/soc/sunxi/daudio0/Kconfig
index 35855b9..06b8292 100755
--- a/sound/soc/sunxi/daudio0/Kconfig
+++ b/sound/soc/sunxi/daudio0/Kconfig
@@ -37,9 +37,16 @@ config SND_SUNXI_SOC_SUN8IW7_RT3261
help
Say Y or M if you want to add rt3261 codec support
+config SND_SUNXI_SOC_SUN8IW7_PCM5102A
+ tristate "Machine for h3 pcm5102a"
+ depends on ARCH_SUN8IW7 && SND_SOC_PCM5102A
+ default n
+ help
+ Say Y or M if you want to add pcm5102a codec support
+
config SND_VIRBB_DAI
tristate "virtual bb interface"
depends on (ARCH_SUN8IW6||ARCH_SUN8IW7)&& MFD_ACX00=y
default n
help
- Say Y or M if you want to add sun8iw1 audiocodec support
\ No newline at end of file
+ Say Y or M if you want to add sun8iw1 audiocodec support
diff --git a/sound/soc/sunxi/daudio0/Makefile b/sound/soc/sunxi/daudio0/Makefile
index f30d406..4dd7b64 100755
--- a/sound/soc/sunxi/daudio0/Makefile
+++ b/sound/soc/sunxi/daudio0/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_SND_SUNXI_SOC_DAUDIO0_KARAOKE_MACHINE) += h3_ac100.o
obj-$(CONFIG_SND_SUNXI_SOC_SUN8IW6_ACX00) += a83_ac100.o
obj-$(CONFIG_SND_SUNXI_SOC_SUN8IW6_ACX00) += a83_ac200.o
obj-$(CONFIG_SND_SUNXI_SOC_SUN8IW7_RT3261) += h3_rt3261.o
+obj-$(CONFIG_SND_SUNXI_SOC_SUN8IW7_PCM5102A) += h3_pcm5102a.o
obj-$(CONFIG_SND_VIRBB_DAI) += bb_dai.o
diff --git a/sound/soc/sunxi/daudio0/h3_pcm5102a.c b/sound/soc/sunxi/daudio0/h3_pcm5102a.c
new file mode 100755
index 0000000..33d191f
--- /dev/null
+++ b/sound/soc/sunxi/daudio0/h3_pcm5102a.c
@@ -0,0 +1,247 @@
+/*
+ * sound\soc\sunxi\daudio\sunxi_snddaudio.c
+ * (C) Copyright 2010-2016
+ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
+ * huangxin <huangxin@Reuuimllatech.com>
+ *
+ * some simple description for this code
+ *
+ * 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 <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <linux/io.h>
+#include <mach/sys_config.h>
+
+#include "sunxi-daudio0.h"
+#include "sunxi-daudiodma0.h"
+
+static bool daudio_pcm_select = 0;
+
+static int daudio_used = 0;
+static int daudio_master = 0;
+static int audio_format = 0;
+static int signal_inversion = 0;
+
+/*
+* daudio_pcm_select == 0:--> pcm
+* daudio_pcm_select == 1:--> i2s
+*/
+static int sunxi_daudio_set_audio_mode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ daudio_pcm_select = ucontrol->value.integer.value[0];
+
+ if (daudio_pcm_select) {
+ audio_format = 1;
+ signal_inversion = 1;
+ daudio_master = 4;
+ } else {
+ audio_format = 4;
+ signal_inversion = 3;
+ daudio_master = 1;
+ }
+
+ return 0;
+}
+
+static int sunxi_daudio_get_audio_mode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = daudio_pcm_select;
+ return 0;
+}
+
+/* I2s Or Pcm Audio Mode Select */
+static const struct snd_kcontrol_new sunxi_daudio_controls[] = {
+ SOC_SINGLE_BOOL_EXT("I2s Or Pcm Audio Mode Select format", 0,
+ sunxi_daudio_get_audio_mode, sunxi_daudio_set_audio_mode),
+};
+
+static int sunxi_snddaudio_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ int ret = 0;
+ u32 freq = 22579200;
+
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ //struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ unsigned long sample_rate = params_rate(params);
+
+ switch (sample_rate) {
+ case 8000:
+ case 16000:
+ case 32000:
+ case 64000:
+ case 128000:
+ case 12000:
+ case 24000:
+ case 48000:
+ case 96000:
+ case 192000:
+ freq = 24576000;
+ break;
+ }
+
+ /*set system clock source freq and set the mode as daudio or pcm*/
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0 , freq, daudio_pcm_select);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = snd_soc_dai_set_fmt(cpu_dai, (audio_format | (signal_inversion<<8) | (daudio_master<<12)));
+ if (ret < 0) {
+ return ret;
+ }
+ ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, sample_rate);
+ if (ret < 0) {
+ return ret;
+ }
+ /*
+ * audio_format == SND_SOC_DAIFMT_DSP_A
+ * signal_inversion<<8 == SND_SOC_DAIFMT_IB_NF
+ * daudio_master<<12 == SND_SOC_DAIFMT_CBM_CFM
+ */
+ DAUDIO_DBG("%s,line:%d,audio_format:%d,SND_SOC_DAIFMT_DSP_A:%d\n",\
+ __func__, __LINE__, audio_format, SND_SOC_DAIFMT_DSP_A);
+ DAUDIO_DBG("%s,line:%d,signal_inversion:%d,signal_inversion<<8:%d,SND_SOC_DAIFMT_IB_NF:%d\n",\
+ __func__, __LINE__, signal_inversion, signal_inversion<<8, SND_SOC_DAIFMT_IB_NF);
+ DAUDIO_DBG("%s,line:%d,daudio_master:%d,daudio_master<<12:%d,SND_SOC_DAIFMT_CBM_CFM:%d\n",\
+ __func__, __LINE__, daudio_master, daudio_master<<12, SND_SOC_DAIFMT_CBM_CFM);
+
+ return 0;
+}
+
+static struct snd_soc_ops sunxi_snddaudio_ops = {
+ .hw_params = sunxi_snddaudio_hw_params,
+};
+
+static struct snd_soc_dai_link sunxi_pcm5102a_dai_link = {
+ .name = "PCM5102A",
+ .cpu_dai_name = "pri_dai",
+ .stream_name = "Playback",
+ .codec_dai_name = "pcm5102a-hifi",
+ .codec_name = "pcm5102a-codec",
+ .platform_name = "sunxi-daudio-pcm-audio.0",
+ .ops = &sunxi_snddaudio_ops,
+ .dai_fmt = (SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF),
+};
+
+static struct snd_soc_card snd_soc_sunxi_pcm5102a = {
+ .name = "Pcm5102a",
+ .owner = THIS_MODULE,
+ .dai_link = &sunxi_pcm5102a_dai_link,
+ .num_links = 1,
+};
+
+static int __devinit sunxi_snddaudio0_dev_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ script_item_u val;
+ script_item_value_type_e type;
+ struct snd_soc_card *card = &snd_soc_sunxi_pcm5102a;
+
+ type = script_get_item(TDM_NAME, "daudio_select", &val);
+ if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
+ pr_err("[I2S0] daudio_select type err!\n");
+ }
+ daudio_pcm_select = val.val;
+
+ type = script_get_item(TDM_NAME, "daudio_master", &val);
+ if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
+ pr_err("[I2S0] daudio_master type err!\n");
+ }
+ daudio_master = val.val;
+
+ type = script_get_item(TDM_NAME, "audio_format", &val);
+ if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
+ pr_err("[I2S0] audio_format type err!\n");
+ }
+ audio_format = val.val;
+
+ type = script_get_item(TDM_NAME, "signal_inversion", &val);
+ if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
+ pr_err("[I2S0] signal_inversion type err!\n");
+ }
+ signal_inversion = val.val;
+
+ card->dev = &pdev->dev;
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+ }
+ return ret;
+}
+
+static int __devexit sunxi_snddaudio0_dev_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ snd_soc_unregister_card(card);
+ return 0;
+}
+
+/*data relating*/
+static struct platform_device sunxi_daudio_device = {
+ .name = "snddaudio",
+ .id = PLATFORM_DEVID_NONE,
+};
+
+/*method relating*/
+static struct platform_driver sunxi_daudio_driver = {
+ .probe = sunxi_snddaudio0_dev_probe,
+ .remove = __exit_p(sunxi_snddaudio0_dev_remove),
+ .driver = {
+ .name = "snddaudio",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+};
+
+static int __init sunxi_snddaudio0_init(void)
+{
+ int err = 0;
+ script_item_u val;
+ script_item_value_type_e type;
+ type = script_get_item(TDM_NAME, "daudio_used", &val);
+ if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
+ pr_err("[daudio0]:%s,line:%d type err!\n", __func__, __LINE__);
+ }
+ daudio_used = val.val;
+ if (daudio_used) {
+ if((err = platform_device_register(&sunxi_daudio_device)) < 0)
+ return err;
+
+ if ((err = platform_driver_register(&sunxi_daudio_driver)) < 0)
+ return err;
+ } else {
+ pr_warning("[DAUDIO0] driver not init,just return.\n");
+ }
+
+ return 0;
+}
+module_init(sunxi_snddaudio0_init);
+
+static void __exit sunxi_snddaudio0_exit(void)
+{
+ if (daudio_used) {
+ daudio_used = 0;
+ platform_driver_unregister(&sunxi_daudio_driver);
+ platform_device_unregister(&sunxi_daudio_device);
+ }
+}
+module_exit(sunxi_snddaudio0_exit);
+MODULE_AUTHOR("huangxin");
+MODULE_DESCRIPTION("SUNXI_snddaudio ALSA SoC audio driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 215d458..3c8d1a5 100755
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -98,6 +98,7 @@ snd-soc-wm9705-objs := wm9705.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
+snd-soc-pcm5102a-objs := pcm5102a.o
snd-soc-rt3261-objs := rt3261/rt3261.o rt3261/rt_codec_ioctl.o rt3261/rt3261_ioctl.o rt3261/rt3261-dsp.o
snd-soc-max9877-objs := max9877.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment