diff options
| author | Marcus Cooper <codekipper@gmail.com> | 2016-02-08 12:09:21 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2016-02-19 11:25:51 -0500 |
| commit | f8260afa444b670016f22f2ba1440d9d2e74dcb6 (patch) | |
| tree | 47ce83c423ad037fe08d1da08f297dc82d044104 | |
| parent | 8020e1bbaa5e8d8340ab78c71a69ccdd362ab203 (diff) | |
ASoC: sunxi: Add support for the SPDIF block
The sun4i, sun5i and sun7i SoC families have an SPDIF
block which is capable of playback and capture.
This patch enables the playback of this block for
the sun4i families.
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | sound/soc/sunxi/Kconfig | 8 | ||||
| -rw-r--r-- | sound/soc/sunxi/Makefile | 1 | ||||
| -rw-r--r-- | sound/soc/sunxi/sun4i-spdif.c | 550 |
3 files changed, 559 insertions, 0 deletions
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig index 84c72ec6ad73..ae42294ef688 100644 --- a/sound/soc/sunxi/Kconfig +++ b/sound/soc/sunxi/Kconfig | |||
| @@ -8,4 +8,12 @@ config SND_SUN4I_CODEC | |||
| 8 | Select Y or M to add support for the Codec embedded in the Allwinner | 8 | Select Y or M to add support for the Codec embedded in the Allwinner |
| 9 | A10 and affiliated SoCs. | 9 | A10 and affiliated SoCs. |
| 10 | 10 | ||
| 11 | config SND_SUN4I_SPDIF | ||
| 12 | tristate "Allwinner A10 SPDIF Support" | ||
| 13 | depends on OF | ||
| 14 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
| 15 | select REGMAP_MMIO | ||
| 16 | help | ||
| 17 | Say Y or M to add support for the S/PDIF audio block in the Allwinner | ||
| 18 | A10 and affiliated SoCs. | ||
| 11 | endmenu | 19 | endmenu |
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile index ea8a08c881d6..8f5e889667f1 100644 --- a/sound/soc/sunxi/Makefile +++ b/sound/soc/sunxi/Makefile | |||
| @@ -1,2 +1,3 @@ | |||
| 1 | obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o | 1 | obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o | ||
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c new file mode 100644 index 000000000000..0b04fb02125c --- /dev/null +++ b/sound/soc/sunxi/sun4i-spdif.c | |||
| @@ -0,0 +1,550 @@ | |||
| 1 | /* | ||
| 2 | * ALSA SoC SPDIF Audio Layer | ||
| 3 | * | ||
| 4 | * Copyright 2015 Andrea Venturi <be17068@iperbole.bo.it> | ||
| 5 | * Copyright 2015 Marcus Cooper <codekipper@gmail.com> | ||
| 6 | * | ||
| 7 | * Based on the Allwinner SDK driver, released under the GPL. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/device.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/regmap.h> | ||
| 26 | #include <linux/of_address.h> | ||
| 27 | #include <linux/of_device.h> | ||
| 28 | #include <linux/ioport.h> | ||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/pm_runtime.h> | ||
| 32 | #include <sound/dmaengine_pcm.h> | ||
| 33 | #include <sound/pcm_params.h> | ||
| 34 | #include <sound/soc.h> | ||
| 35 | |||
| 36 | #define SUN4I_SPDIF_CTL (0x00) | ||
| 37 | #define SUN4I_SPDIF_CTL_MCLKDIV(v) ((v) << 4) /* v even */ | ||
| 38 | #define SUN4I_SPDIF_CTL_MCLKOUTEN BIT(2) | ||
| 39 | #define SUN4I_SPDIF_CTL_GEN BIT(1) | ||
| 40 | #define SUN4I_SPDIF_CTL_RESET BIT(0) | ||
| 41 | |||
| 42 | #define SUN4I_SPDIF_TXCFG (0x04) | ||
| 43 | #define SUN4I_SPDIF_TXCFG_SINGLEMOD BIT(31) | ||
| 44 | #define SUN4I_SPDIF_TXCFG_ASS BIT(17) | ||
| 45 | #define SUN4I_SPDIF_TXCFG_NONAUDIO BIT(16) | ||
| 46 | #define SUN4I_SPDIF_TXCFG_TXRATIO(v) ((v) << 4) | ||
| 47 | #define SUN4I_SPDIF_TXCFG_TXRATIO_MASK GENMASK(8, 4) | ||
| 48 | #define SUN4I_SPDIF_TXCFG_FMTRVD GENMASK(3, 2) | ||
| 49 | #define SUN4I_SPDIF_TXCFG_FMT16BIT (0 << 2) | ||
| 50 | #define SUN4I_SPDIF_TXCFG_FMT20BIT (1 << 2) | ||
| 51 | #define SUN4I_SPDIF_TXCFG_FMT24BIT (2 << 2) | ||
| 52 | #define SUN4I_SPDIF_TXCFG_CHSTMODE BIT(1) | ||
| 53 | #define SUN4I_SPDIF_TXCFG_TXEN BIT(0) | ||
| 54 | |||
| 55 | #define SUN4I_SPDIF_RXCFG (0x08) | ||
| 56 | #define SUN4I_SPDIF_RXCFG_LOCKFLAG BIT(4) | ||
| 57 | #define SUN4I_SPDIF_RXCFG_CHSTSRC BIT(3) | ||
| 58 | #define SUN4I_SPDIF_RXCFG_CHSTCP BIT(1) | ||
| 59 | #define SUN4I_SPDIF_RXCFG_RXEN BIT(0) | ||
| 60 | |||
| 61 | #define SUN4I_SPDIF_TXFIFO (0x0C) | ||
| 62 | |||
| 63 | #define SUN4I_SPDIF_RXFIFO (0x10) | ||
| 64 | |||
| 65 | #define SUN4I_SPDIF_FCTL (0x14) | ||
| 66 | #define SUN4I_SPDIF_FCTL_FIFOSRC BIT(31) | ||
| 67 | #define SUN4I_SPDIF_FCTL_FTX BIT(17) | ||
| 68 | #define SUN4I_SPDIF_FCTL_FRX BIT(16) | ||
| 69 | #define SUN4I_SPDIF_FCTL_TXTL(v) ((v) << 8) | ||
| 70 | #define SUN4I_SPDIF_FCTL_TXTL_MASK GENMASK(12, 8) | ||
| 71 | #define SUN4I_SPDIF_FCTL_RXTL(v) ((v) << 3) | ||
| 72 | #define SUN4I_SPDIF_FCTL_RXTL_MASK GENMASK(7, 3) | ||
| 73 | #define SUN4I_SPDIF_FCTL_TXIM BIT(2) | ||
| 74 | #define SUN4I_SPDIF_FCTL_RXOM(v) ((v) << 0) | ||
| 75 | #define SUN4I_SPDIF_FCTL_RXOM_MASK GENMASK(1, 0) | ||
| 76 | |||
| 77 | #define SUN4I_SPDIF_FSTA (0x18) | ||
| 78 | #define SUN4I_SPDIF_FSTA_TXE BIT(14) | ||
| 79 | #define SUN4I_SPDIF_FSTA_TXECNTSHT (8) | ||
| 80 | #define SUN4I_SPDIF_FSTA_RXA BIT(6) | ||
| 81 | #define SUN4I_SPDIF_FSTA_RXACNTSHT (0) | ||
| 82 | |||
| 83 | #define SUN4I_SPDIF_INT (0x1C) | ||
| 84 | #define SUN4I_SPDIF_INT_RXLOCKEN BIT(18) | ||
| 85 | #define SUN4I_SPDIF_INT_RXUNLOCKEN BIT(17) | ||
| 86 | #define SUN4I_SPDIF_INT_RXPARERREN BIT(16) | ||
| 87 | #define SUN4I_SPDIF_INT_TXDRQEN BIT(7) | ||
| 88 | #define SUN4I_SPDIF_INT_TXUIEN BIT(6) | ||
| 89 | #define SUN4I_SPDIF_INT_TXOIEN BIT(5) | ||
| 90 | #define SUN4I_SPDIF_INT_TXEIEN BIT(4) | ||
| 91 | #define SUN4I_SPDIF_INT_RXDRQEN BIT(2) | ||
| 92 | #define SUN4I_SPDIF_INT_RXOIEN BIT(1) | ||
| 93 | #define SUN4I_SPDIF_INT_RXAIEN BIT(0) | ||
| 94 | |||
| 95 | #define SUN4I_SPDIF_ISTA (0x20) | ||
| 96 | #define SUN4I_SPDIF_ISTA_RXLOCKSTA BIT(18) | ||
| 97 | #define SUN4I_SPDIF_ISTA_RXUNLOCKSTA BIT(17) | ||
| 98 | #define SUN4I_SPDIF_ISTA_RXPARERRSTA BIT(16) | ||
| 99 | #define SUN4I_SPDIF_ISTA_TXUSTA BIT(6) | ||
| 100 | #define SUN4I_SPDIF_ISTA_TXOSTA BIT(5) | ||
| 101 | #define SUN4I_SPDIF_ISTA_TXESTA BIT(4) | ||
| 102 | #define SUN4I_SPDIF_ISTA_RXOSTA BIT(1) | ||
| 103 | #define SUN4I_SPDIF_ISTA_RXASTA BIT(0) | ||
| 104 | |||
| 105 | #define SUN4I_SPDIF_TXCNT (0x24) | ||
| 106 | |||
| 107 | #define SUN4I_SPDIF_RXCNT (0x28) | ||
| 108 | |||
| 109 | #define SUN4I_SPDIF_TXCHSTA0 (0x2C) | ||
| 110 | #define SUN4I_SPDIF_TXCHSTA0_CLK(v) ((v) << 28) | ||
| 111 | #define SUN4I_SPDIF_TXCHSTA0_SAMFREQ(v) ((v) << 24) | ||
| 112 | #define SUN4I_SPDIF_TXCHSTA0_SAMFREQ_MASK GENMASK(27, 24) | ||
| 113 | #define SUN4I_SPDIF_TXCHSTA0_CHNUM(v) ((v) << 20) | ||
| 114 | #define SUN4I_SPDIF_TXCHSTA0_CHNUM_MASK GENMASK(23, 20) | ||
| 115 | #define SUN4I_SPDIF_TXCHSTA0_SRCNUM(v) ((v) << 16) | ||
| 116 | #define SUN4I_SPDIF_TXCHSTA0_CATACOD(v) ((v) << 8) | ||
| 117 | #define SUN4I_SPDIF_TXCHSTA0_MODE(v) ((v) << 6) | ||
| 118 | #define SUN4I_SPDIF_TXCHSTA0_EMPHASIS(v) ((v) << 3) | ||
| 119 | #define SUN4I_SPDIF_TXCHSTA0_CP BIT(2) | ||
| 120 | #define SUN4I_SPDIF_TXCHSTA0_AUDIO BIT(1) | ||
| 121 | #define SUN4I_SPDIF_TXCHSTA0_PRO BIT(0) | ||
| 122 | |||
| 123 | #define SUN4I_SPDIF_TXCHSTA1 (0x30) | ||
| 124 | #define SUN4I_SPDIF_TXCHSTA1_CGMSA(v) ((v) << 8) | ||
| 125 | #define SUN4I_SPDIF_TXCHSTA1_ORISAMFREQ(v) ((v) << 4) | ||
| 126 | #define SUN4I_SPDIF_TXCHSTA1_ORISAMFREQ_MASK GENMASK(7, 4) | ||
| 127 | #define SUN4I_SPDIF_TXCHSTA1_SAMWORDLEN(v) ((v) << 1) | ||
| 128 | #define SUN4I_SPDIF_TXCHSTA1_MAXWORDLEN BIT(0) | ||
| 129 | |||
| 130 | #define SUN4I_SPDIF_RXCHSTA0 (0x34) | ||
| 131 | #define SUN4I_SPDIF_RXCHSTA0_CLK(v) ((v) << 28) | ||
| 132 | #define SUN4I_SPDIF_RXCHSTA0_SAMFREQ(v) ((v) << 24) | ||
| 133 | #define SUN4I_SPDIF_RXCHSTA0_CHNUM(v) ((v) << 20) | ||
| 134 | #define SUN4I_SPDIF_RXCHSTA0_SRCNUM(v) ((v) << 16) | ||
| 135 | #define SUN4I_SPDIF_RXCHSTA0_CATACOD(v) ((v) << 8) | ||
| 136 | #define SUN4I_SPDIF_RXCHSTA0_MODE(v) ((v) << 6) | ||
| 137 | #define SUN4I_SPDIF_RXCHSTA0_EMPHASIS(v) ((v) << 3) | ||
| 138 | #define SUN4I_SPDIF_RXCHSTA0_CP BIT(2) | ||
| 139 | #define SUN4I_SPDIF_RXCHSTA0_AUDIO BIT(1) | ||
| 140 | #define SUN4I_SPDIF_RXCHSTA0_PRO BIT(0) | ||
| 141 | |||
| 142 | #define SUN4I_SPDIF_RXCHSTA1 (0x38) | ||
| 143 | #define SUN4I_SPDIF_RXCHSTA1_CGMSA(v) ((v) << 8) | ||
| 144 | #define SUN4I_SPDIF_RXCHSTA1_ORISAMFREQ(v) ((v) << 4) | ||
| 145 | #define SUN4I_SPDIF_RXCHSTA1_SAMWORDLEN(v) ((v) << 1) | ||
| 146 | #define SUN4I_SPDIF_RXCHSTA1_MAXWORDLEN BIT(0) | ||
| 147 | |||
| 148 | /* Defines for Sampling Frequency */ | ||
| 149 | #define SUN4I_SPDIF_SAMFREQ_44_1KHZ 0x0 | ||
| 150 | #define SUN4I_SPDIF_SAMFREQ_NOT_INDICATED 0x1 | ||
| 151 | #define SUN4I_SPDIF_SAMFREQ_48KHZ 0x2 | ||
| 152 | #define SUN4I_SPDIF_SAMFREQ_32KHZ 0x3 | ||
| 153 | #define SUN4I_SPDIF_SAMFREQ_22_05KHZ 0x4 | ||
| 154 | #define SUN4I_SPDIF_SAMFREQ_24KHZ 0x6 | ||
| 155 | #define SUN4I_SPDIF_SAMFREQ_88_2KHZ 0x8 | ||
| 156 | #define SUN4I_SPDIF_SAMFREQ_76_8KHZ 0x9 | ||
| 157 | #define SUN4I_SPDIF_SAMFREQ_96KHZ 0xa | ||
| 158 | #define SUN4I_SPDIF_SAMFREQ_176_4KHZ 0xc | ||
| 159 | #define SUN4I_SPDIF_SAMFREQ_192KHZ 0xe | ||
| 160 | |||
| 161 | struct sun4i_spdif_dev { | ||
| 162 | struct platform_device *pdev; | ||
| 163 | struct clk *spdif_clk; | ||
| 164 | struct clk *apb_clk; | ||
| 165 | struct snd_soc_dai_driver cpu_dai_drv; | ||
| 166 | struct regmap *regmap; | ||
| 167 | struct snd_dmaengine_dai_dma_data dma_params_tx; | ||
| 168 | }; | ||
| 169 | |||
| 170 | static void sun4i_spdif_configure(struct sun4i_spdif_dev *host) | ||
| 171 | { | ||
| 172 | /* soft reset SPDIF */ | ||
| 173 | regmap_write(host->regmap, SUN4I_SPDIF_CTL, SUN4I_SPDIF_CTL_RESET); | ||
| 174 | |||
| 175 | /* flush TX FIFO */ | ||
