Created
February 20, 2017 02:17
-
-
Save Simon-L/c8c119c86d7d3fe4316387c3ae818379 to your computer and use it in GitHub Desktop.
PCM5102a patches for Armbian on nanopiair
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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