From 5c9b97d145d43e44897a5c628ca9b10ece398189 Mon Sep 17 00:00:00 2001 From: James <> Date: Fri, 2 Oct 2015 12:43:16 +0100 Subject: nearly working audio --- master/audio | 478 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 master/audio (limited to 'master/audio') diff --git a/master/audio b/master/audio new file mode 100644 index 0000000..650f224 --- /dev/null +++ b/master/audio @@ -0,0 +1,478 @@ +diff --git a/.config b/.config +index f832165..10dcb5d 100644 +--- a/.config ++++ b/.config +@@ -1410,8 +1410,15 @@ CONFIG_PACKAGE_gdbserver=m + # + # I2C support + # +-# CONFIG_PACKAGE_kmod-i2c-core is not set ++CONFIG_PACKAGE_kmod-i2c-core=y ++# CONFIG_PACKAGE_kmod-i2c-algo-bit is not set ++# CONFIG_PACKAGE_kmod-i2c-algo-pca is not set ++# CONFIG_PACKAGE_kmod-i2c-algo-pcf is not set ++# CONFIG_PACKAGE_kmod-i2c-gpio is not set + # CONFIG_PACKAGE_kmod-i2c-gpio-custom is not set ++# CONFIG_PACKAGE_kmod-i2c-mux is not set ++CONFIG_PACKAGE_kmod-i2c-ralink=y ++# CONFIG_PACKAGE_kmod-i2c-tiny-usb is not set + CONFIG_PACKAGE_kmod-kkmoon-motors=y + + # +@@ -1456,7 +1463,7 @@ CONFIG_PACKAGE_kmod-lib-crc-itu-t=y + # CONFIG_PACKAGE_kmod-lib-crc7 is not set + # CONFIG_PACKAGE_kmod-lib-crc8 is not set + # CONFIG_PACKAGE_kmod-lib-lz4 is not set +-# CONFIG_PACKAGE_kmod-lib-lzo is not set ++CONFIG_PACKAGE_kmod-lib-lzo=y + # CONFIG_PACKAGE_kmod-lib-textsearch is not set + # CONFIG_PACKAGE_kmod-lib-zlib is not set + +@@ -1651,7 +1658,7 @@ CONFIG_PACKAGE_kmod-gpio-button-hotplug=y + # CONFIG_PACKAGE_kmod-pps-gpio is not set + # CONFIG_PACKAGE_kmod-ptp is not set + # CONFIG_PACKAGE_kmod-random-core is not set +-# CONFIG_PACKAGE_kmod-regmap is not set ++CONFIG_PACKAGE_kmod-regmap=y + # CONFIG_PACKAGE_kmod-rotary-gpio-custom is not set + # CONFIG_PACKAGE_kmod-sdhci is not set + # CONFIG_PACKAGE_kmod-serial-8250 is not set +@@ -1675,12 +1682,13 @@ CONFIG_PACKAGE_kmod-gpio-button-hotplug=y + # + # Sound Support + # +-CONFIG_PACKAGE_kmod-sound-core=m +-# CONFIG_PACKAGE_kmod-ac97 is not set ++CONFIG_PACKAGE_kmod-sound-core=y ++CONFIG_PACKAGE_kmod-ac97=y + # CONFIG_PACKAGE_kmod-sound-i8x0 is not set ++CONFIG_PACKAGE_kmod-sound-rt5350=y + # CONFIG_PACKAGE_kmod-sound-seq is not set + # CONFIG_PACKAGE_kmod-sound-soc-ac97 is not set +-# CONFIG_PACKAGE_kmod-sound-soc-core is not set ++CONFIG_PACKAGE_kmod-sound-soc-core=y + CONFIG_PACKAGE_kmod-usb-audio=m + + # +diff --git a/target/linux/ramips/dts/TP-C516W-common.dtsi b/target/linux/ramips/dts/TP-C516W-common.dtsi +index 675f83a..368c387 100644 +--- a/target/linux/ramips/dts/TP-C516W-common.dtsi ++++ b/target/linux/ramips/dts/TP-C516W-common.dtsi +@@ -5,6 +5,20 @@ + status = "ok"; + }; + ++ i2c@900 { ++ status = "ok"; ++ }; ++ ++ i2s: i2s@a00 { ++ status = "ok"; ++ ++/* ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_gpio_pins>; ++*/ ++ ++ }; ++ + spi@b00 { + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; +@@ -12,13 +26,50 @@ + + }; + ++ ++ audio { ++ compatible = "ralink,rt5350-audio-cjc8988"; ++ i2s-controller = <&i2s>; ++ audio-codec = <&codec>; ++ }; ++ ++ codec: codec { ++ compatible = "wlf,wm8988", "chinaic,cjc8988"; ++ }; ++ ++ + pinctrl { ++ i2s_gpio_pins: i2s { ++ i2s { ++ ralink,group = "uartf"; ++ ralink,function = "gpio i2s"; ++ }; ++ }; ++ ++ + state_default: pinctrl0 { + gpio { +- ralink,group = "jtag", "rgmii", "mdio", "led", "spi_cs1", "uartf"; ++ ralink,group = "jtag", "rgmii", "mdio", "led", "spi_cs1"; + ralink,function = "gpio"; + }; ++ ++ /* Do this here as it crosses two functions */ ++ i2s { ++ ralink,group = "uartf"; ++ ralink,function = "gpio i2s"; ++ }; ++ }; ++ ++/* ++ i2s_gpio_pins: i2s { ++ i2s { ++ ralink,group = "uartf"; ++ ralink,function = "gpio i2s"; ++ }; + }; ++*/ ++ ++ + }; + + gpio-leds { +diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk +index 673fa61..9088a2e 100644 +--- a/target/linux/ramips/modules.mk ++++ b/target/linux/ramips/modules.mk +@@ -88,3 +88,24 @@ define KernelPackage/sound-mt7620/description + endef + + $(eval $(call KernelPackage,sound-mt7620)) ++ ++ ++define KernelPackage/sound-rt5350 ++ TITLE:=RT5350 PCM/I2S Alsa Driver ++ DEPENDS:=@TARGET_ramips +kmod-sound-soc-core +kmod-regmap ++ KCONFIG:= \ ++ CONFIG_SND_MT7620_SOC_I2S \ ++ CONFIG_SND_RT5350_SOC_WM8988 ++ FILES:= \ ++ $(LINUX_DIR)/sound/soc/ralink/snd-soc-mt7620-i2s.ko \ ++ $(LINUX_DIR)/sound/soc/ralink/snd-soc-rt5350-wm8988.ko \ ++ $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8988.ko ++ AUTOLOAD:=$(call AutoLoad,90,snd-soc-wm8960 snd-soc-mt7620-i2s snd-soc-mt7620-wm8960) ++ $(call AddDepends/sound) ++endef ++ ++define KernelPackage/sound-rt5350/description ++ Alsa modules for ralink i2s controller. ++endef ++ ++$(eval $(call KernelPackage,sound-rt5350)) +diff --git a/target/linux/ramips/patches-3.18/9998-rt5350-i2s.patch b/target/linux/ramips/patches-3.18/9998-rt5350-i2s.patch +new file mode 100644 +index 0000000..b7d7754 +--- /dev/null ++++ b/target/linux/ramips/patches-3.18/9998-rt5350-i2s.patch +@@ -0,0 +1,310 @@ ++Index: linux-3.18.21/sound/soc/ralink/mt7620-i2s.c ++=================================================================== ++--- linux-3.18.21.orig/sound/soc/ralink/mt7620-i2s.c +++++ linux-3.18.21/sound/soc/ralink/mt7620-i2s.c ++@@ -414,6 +414,7 @@ static int mt7620_i2s_dev_remove(struct ++ ++ static const struct of_device_id mt7620_i2s_match[] = { ++ { .compatible = "ralink,mt7620a-i2s" }, +++ { .compatible = "ralink,rt5350-i2s" }, ++ {}, ++ }; ++ MODULE_DEVICE_TABLE(of, mt7620_i2s_match); ++Index: linux-3.18.21/sound/soc/ralink/Kconfig ++=================================================================== ++--- linux-3.18.21.orig/sound/soc/ralink/Kconfig +++++ linux-3.18.21/sound/soc/ralink/Kconfig ++@@ -1,7 +1,7 @@ ++ config SND_MT7620_SOC_I2S ++- depends on SOC_MT7620 && SND_SOC +++ depends on (SOC_RT305X || SOC_MT7620) && SND_SOC ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++- tristate "SoC Audio (I2S protocol) for Ralink MT7620 SoC" +++ tristate "SoC Audio (I2S protocol) for Ralink RT5350 and MT7620 SoC" ++ help ++ Say Y if you want to use I2S protocol and I2S codec on Ingenic MT7620 ++ based boards. ++@@ -13,3 +13,11 @@ config SND_MT7620_SOC_WM8960 ++ help ++ Say Y if you want to add support for ASoC audio on the Qi LB60 board ++ a.k.a Qi Ben NanoNote. +++ +++config SND_RT5350_SOC_WM8988 +++ tristate "SoC Audio support for Ralink WM8988" +++ select SND_MT7620_SOC_I2S +++ select SND_SOC_WM8988 +++ help +++ Say Y if you want to add support for ASoC audio on the Qi LB60 board +++ a.k.a Qi Ben NanoNote. ++Index: linux-3.18.21/sound/soc/codecs/wm8988.c ++=================================================================== ++--- linux-3.18.21.orig/sound/soc/codecs/wm8988.c +++++ linux-3.18.21/sound/soc/codecs/wm8988.c ++@@ -942,9 +942,17 @@ static const struct i2c_device_id wm8988 ++ }; ++ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); ++ +++ +++static const struct of_device_id wm8988_of_match[] = { +++ { .compatible = "wlf,wm8988", }, +++ { } +++}; +++MODULE_DEVICE_TABLE(of, wm8962_of_match); +++ ++ static struct i2c_driver wm8988_i2c_driver = { ++ .driver = { ++ .name = "wm8988", +++ .of_match_table = wm8988_of_match, ++ .owner = THIS_MODULE, ++ }, ++ .probe = wm8988_i2c_probe, ++Index: linux-3.18.21/sound/soc/ralink/Makefile ++=================================================================== ++--- linux-3.18.21.orig/sound/soc/ralink/Makefile +++++ linux-3.18.21/sound/soc/ralink/Makefile ++@@ -9,3 +9,7 @@ obj-$(CONFIG_SND_MT7620_SOC_I2S) += snd- ++ snd-soc-mt7620-wm8960-objs := mt7620-wm8960.o ++ ++ obj-$(CONFIG_SND_MT7620_SOC_WM8960) += snd-soc-mt7620-wm8960.o +++ +++snd-soc-rt5350-wm8988-objs := rt5350-wm8988.o +++ +++obj-$(CONFIG_SND_RT5350_SOC_WM8988) += snd-soc-rt5350-wm8988.o ++Index: linux-3.18.21/sound/soc/ralink/rt5350-wm8988.c ++=================================================================== ++--- /dev/null +++++ linux-3.18.21/sound/soc/ralink/rt5350-wm8988.c ++@@ -0,0 +1,233 @@ +++/* +++ * Copyright 2013 Freescale Semiconductor, Inc. +++ * +++ * Based on rt5350-sgtl5000.c +++ * Copyright 2012 Freescale Semiconductor, Inc. +++ * Copyright 2012 Linaro Ltd. +++ * +++ * The code contained herein is licensed under the GNU General Public +++ * License. You may obtain a copy of the GNU General Public License +++ * Version 2 or later at the following locations: +++ * +++ * http://www.opensource.org/licenses/gpl-license.html +++ * http://www.gnu.org/copyleft/gpl.html +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#include "../codecs/wm8960.h" +++ +++#define DAI_NAME_SIZE 32 +++ +++struct rt5350_wm8960_data { +++ struct snd_soc_dai_link dai; +++ struct snd_soc_card card; +++ char codec_dai_name[DAI_NAME_SIZE]; +++ char platform_name[DAI_NAME_SIZE]; +++ unsigned int clk_frequency; +++}; +++ +++struct rt5350_priv { +++ struct platform_device *pdev; +++}; +++static struct rt5350_priv card_priv; +++ +++static const struct snd_soc_dapm_widget rt5350_wm8960_dapm_widgets[] = { +++ SND_SOC_DAPM_HP("Headphone Jack", NULL), +++ SND_SOC_DAPM_SPK("Ext Spk", NULL), +++ SND_SOC_DAPM_MIC("AMIC", NULL), +++ SND_SOC_DAPM_MIC("DMIC", NULL), +++}; +++ +++static int sample_rate = 44100; +++static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE; +++ +++static int rt5350_hifi_hw_params(struct snd_pcm_substream *substream, +++ struct snd_pcm_hw_params *params) +++{ +++ sample_rate = params_rate(params); +++ sample_format = params_format(params); +++ +++ return 0; +++} +++ +++static struct snd_soc_ops rt5350_hifi_ops = { +++ .hw_params = rt5350_hifi_hw_params, +++}; +++ +++static int rt5350_wm8960_set_bias_level(struct snd_soc_card *card, +++ struct snd_soc_dapm_context *dapm, +++ enum snd_soc_bias_level level) +++{ +++ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; +++ struct rt5350_priv *priv = &card_priv; +++ struct rt5350_wm8960_data *data = snd_soc_card_get_drvdata(card); +++ struct device *dev = &priv->pdev->dev; +++ int ret; +++ +++ if (dapm->dev != codec_dai->dev) +++ return 0; +++ +++ switch (level) { +++ case SND_SOC_BIAS_PREPARE: +++ if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { +++ } +++ break; +++ +++ case SND_SOC_BIAS_STANDBY: +++ if (dapm->bias_level == SND_SOC_BIAS_PREPARE) { +++ ret = snd_soc_dai_set_sysclk(codec_dai, +++ WM8960_SYSCLK_MCLK, data->clk_frequency, +++ SND_SOC_CLOCK_IN); +++ if (ret < 0) { +++ dev_err(dev, +++ "failed to switch away from FLL: %d\n", +++ ret); +++ return ret; +++ } +++ } +++ break; +++ +++ default: +++ break; +++ } +++ +++ return 0; +++} +++ +++static int rt5350_wm8960_late_probe(struct snd_soc_card *card) +++{ +++ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; +++ struct rt5350_priv *priv = &card_priv; +++ struct rt5350_wm8960_data *data = snd_soc_card_get_drvdata(card); +++ struct device *dev = &priv->pdev->dev; +++ int ret; +++ +++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8960_SYSCLK_MCLK, +++ data->clk_frequency, SND_SOC_CLOCK_IN); +++ if (ret < 0) +++ dev_err(dev, "failed to set sysclk in %s\n", __func__); +++ +++ return ret; +++} +++ +++static int rt5350_wm8960_probe(struct platform_device *pdev) +++{ +++ struct device_node *i2s_np, *codec_np; +++ struct platform_device *i2s_pdev; +++ struct rt5350_priv *priv = &card_priv; +++ struct i2c_client *codec_dev; +++ struct rt5350_wm8960_data *data; +++ int ret; +++ +++ priv->pdev = pdev; +++ +++ i2s_np = of_parse_phandle(pdev->dev.of_node, "i2s-controller", 0); +++ codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0); +++ if (!i2s_np || !codec_np) { +++ dev_err(&pdev->dev, "phandle missing or invalid\n"); +++ ret = -EINVAL; +++ goto fail; +++ } +++ +++ i2s_pdev = of_find_device_by_node(i2s_np); +++ if (!i2s_pdev) { +++ dev_err(&pdev->dev, "failed to find SSI platform device\n"); +++ ret = -EINVAL; +++ goto fail; +++ } +++ codec_dev = of_find_i2c_device_by_node(codec_np); +++ if (!codec_dev || !codec_dev->dev.driver) { +++ dev_err(&pdev->dev, "failed to find codec platform device\n"); +++ ret = -EINVAL; +++ goto fail; +++ } +++ +++ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); +++ if (!data) { +++ ret = -ENOMEM; +++ goto fail; +++ } +++ +++ data->clk_frequency = 12000000; +++ data->dai.name = "HiFi"; +++ data->dai.stream_name = "HiFi"; +++ data->dai.codec_dai_name = "wm8960-hifi"; +++ data->dai.codec_of_node = codec_np; +++ data->dai.cpu_dai_name = dev_name(&i2s_pdev->dev); +++ data->dai.platform_of_node = i2s_np; +++ data->dai.ops = &rt5350_hifi_ops; +++ data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | +++ SND_SOC_DAIFMT_CBM_CFM; +++ +++ data->card.dev = &pdev->dev; +++ ret = snd_soc_of_parse_card_name(&data->card, "model"); +++ if (ret) +++ goto fail; +++ ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); +++ if (ret) +++ goto fail; +++ data->card.num_links = 1; +++ data->card.dai_link = &data->dai; +++ data->card.dapm_widgets = rt5350_wm8960_dapm_widgets; +++ data->card.num_dapm_widgets = ARRAY_SIZE(rt5350_wm8960_dapm_widgets); +++ +++ data->card.late_probe = rt5350_wm8960_late_probe; +++ data->card.set_bias_level = rt5350_wm8960_set_bias_level; +++ +++ platform_set_drvdata(pdev, &data->card); +++ snd_soc_card_set_drvdata(&data->card, data); +++ +++ ret = devm_snd_soc_register_card(&pdev->dev, &data->card); +++ if (ret) { +++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); +++ goto fail; +++ } +++ +++ of_node_put(i2s_np); +++ of_node_put(codec_np); +++ +++ return 0; +++fail: +++ if (i2s_np) +++ of_node_put(i2s_np); +++ if (codec_np) +++ of_node_put(codec_np); +++ +++ return ret; +++} +++ +++static int rt5350_wm8960_remove(struct platform_device *pdev) +++{ +++ return 0; +++} +++ +++static const struct of_device_id rt5350_wm8960_dt_ids[] = { +++ { .compatible = "ralink,rt5350-audio-cjc8988", }, +++ { /* sentinel */ } +++}; +++MODULE_DEVICE_TABLE(of, rt5350_wm8960_dt_ids); +++ +++static struct platform_driver rt5350_wm8960_driver = { +++ .driver = { +++ .name = "rt5350-wm8960", +++ .owner = THIS_MODULE, +++ .pm = &snd_soc_pm_ops, +++ .of_match_table = rt5350_wm8960_dt_ids, +++ }, +++ .probe = rt5350_wm8960_probe, +++ .remove = rt5350_wm8960_remove, +++}; +++module_platform_driver(rt5350_wm8960_driver); +++ +++MODULE_AUTHOR("Freescale Semiconductor, Inc."); +++MODULE_DESCRIPTION("Freescale i.MX WM8962 ASoC machine driver"); +++MODULE_LICENSE("GPL v2"); +++MODULE_ALIAS("platform:rt5350-wm8962"); -- cgit v1.2.3