1f9b95980Sapatard@mandriva.com /* 2f9b95980Sapatard@mandriva.com * kirkwood-i2s.c 3f9b95980Sapatard@mandriva.com * 4f9b95980Sapatard@mandriva.com * (c) 2010 Arnaud Patard <apatard@mandriva.com> 569737897SArnaud Patard (Rtp) * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org> 6f9b95980Sapatard@mandriva.com * 7f9b95980Sapatard@mandriva.com * This program is free software; you can redistribute it and/or modify it 8f9b95980Sapatard@mandriva.com * under the terms of the GNU General Public License as published by the 9f9b95980Sapatard@mandriva.com * Free Software Foundation; either version 2 of the License, or (at your 10f9b95980Sapatard@mandriva.com * option) any later version. 11f9b95980Sapatard@mandriva.com */ 12f9b95980Sapatard@mandriva.com 13f9b95980Sapatard@mandriva.com #include <linux/init.h> 14f9b95980Sapatard@mandriva.com #include <linux/module.h> 15f9b95980Sapatard@mandriva.com #include <linux/platform_device.h> 16f9b95980Sapatard@mandriva.com #include <linux/io.h> 17f9b95980Sapatard@mandriva.com #include <linux/slab.h> 18f9b95980Sapatard@mandriva.com #include <linux/mbus.h> 19f9b95980Sapatard@mandriva.com #include <linux/delay.h> 20e919c716SAndrew Lunn #include <linux/clk.h> 21f9b95980Sapatard@mandriva.com #include <sound/pcm.h> 22f9b95980Sapatard@mandriva.com #include <sound/pcm_params.h> 23f9b95980Sapatard@mandriva.com #include <sound/soc.h> 24c02cecb9SArnd Bergmann #include <linux/platform_data/asoc-kirkwood.h> 25eb632318SJean-Francois Moine #include <linux/of.h> 26eb632318SJean-Francois Moine 27f9b95980Sapatard@mandriva.com #include "kirkwood.h" 28f9b95980Sapatard@mandriva.com 2964ddf1f8SRussell King #define DRV_NAME "mvebu-audio" 30f9b95980Sapatard@mandriva.com 31f9b95980Sapatard@mandriva.com #define KIRKWOOD_I2S_FORMATS \ 32f9b95980Sapatard@mandriva.com (SNDRV_PCM_FMTBIT_S16_LE | \ 33f9b95980Sapatard@mandriva.com SNDRV_PCM_FMTBIT_S24_LE | \ 34f9b95980Sapatard@mandriva.com SNDRV_PCM_FMTBIT_S32_LE) 35f9b95980Sapatard@mandriva.com 36f9b95980Sapatard@mandriva.com static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 37f9b95980Sapatard@mandriva.com unsigned int fmt) 38f9b95980Sapatard@mandriva.com { 39f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai); 40f9b95980Sapatard@mandriva.com unsigned long mask; 41f9b95980Sapatard@mandriva.com unsigned long value; 42f9b95980Sapatard@mandriva.com 43f9b95980Sapatard@mandriva.com switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 44f9b95980Sapatard@mandriva.com case SND_SOC_DAIFMT_RIGHT_J: 45f9b95980Sapatard@mandriva.com mask = KIRKWOOD_I2S_CTL_RJ; 46f9b95980Sapatard@mandriva.com break; 47f9b95980Sapatard@mandriva.com case SND_SOC_DAIFMT_LEFT_J: 48f9b95980Sapatard@mandriva.com mask = KIRKWOOD_I2S_CTL_LJ; 49f9b95980Sapatard@mandriva.com break; 50f9b95980Sapatard@mandriva.com case SND_SOC_DAIFMT_I2S: 51f9b95980Sapatard@mandriva.com mask = KIRKWOOD_I2S_CTL_I2S; 52f9b95980Sapatard@mandriva.com break; 53f9b95980Sapatard@mandriva.com default: 54f9b95980Sapatard@mandriva.com return -EINVAL; 55f9b95980Sapatard@mandriva.com } 56f9b95980Sapatard@mandriva.com 57f9b95980Sapatard@mandriva.com /* 58f9b95980Sapatard@mandriva.com * Set same format for playback and record 59f9b95980Sapatard@mandriva.com * This avoids some troubles. 60f9b95980Sapatard@mandriva.com */ 61f9b95980Sapatard@mandriva.com value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL); 62f9b95980Sapatard@mandriva.com value &= ~KIRKWOOD_I2S_CTL_JUST_MASK; 63f9b95980Sapatard@mandriva.com value |= mask; 64f9b95980Sapatard@mandriva.com writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL); 65f9b95980Sapatard@mandriva.com 66f9b95980Sapatard@mandriva.com value = readl(priv->io+KIRKWOOD_I2S_RECCTL); 67f9b95980Sapatard@mandriva.com value &= ~KIRKWOOD_I2S_CTL_JUST_MASK; 68f9b95980Sapatard@mandriva.com value |= mask; 69f9b95980Sapatard@mandriva.com writel(value, priv->io+KIRKWOOD_I2S_RECCTL); 70f9b95980Sapatard@mandriva.com 71f9b95980Sapatard@mandriva.com return 0; 72f9b95980Sapatard@mandriva.com } 73f9b95980Sapatard@mandriva.com 74f9b95980Sapatard@mandriva.com static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) 75f9b95980Sapatard@mandriva.com { 76f9b95980Sapatard@mandriva.com unsigned long value; 77f9b95980Sapatard@mandriva.com 78f9b95980Sapatard@mandriva.com value = KIRKWOOD_DCO_CTL_OFFSET_0; 79f9b95980Sapatard@mandriva.com switch (rate) { 80f9b95980Sapatard@mandriva.com default: 81f9b95980Sapatard@mandriva.com case 44100: 82f9b95980Sapatard@mandriva.com value |= KIRKWOOD_DCO_CTL_FREQ_11; 83f9b95980Sapatard@mandriva.com break; 84f9b95980Sapatard@mandriva.com case 48000: 85f9b95980Sapatard@mandriva.com value |= KIRKWOOD_DCO_CTL_FREQ_12; 86f9b95980Sapatard@mandriva.com break; 87f9b95980Sapatard@mandriva.com case 96000: 88f9b95980Sapatard@mandriva.com value |= KIRKWOOD_DCO_CTL_FREQ_24; 89f9b95980Sapatard@mandriva.com break; 90f9b95980Sapatard@mandriva.com } 91f9b95980Sapatard@mandriva.com writel(value, io + KIRKWOOD_DCO_CTL); 92f9b95980Sapatard@mandriva.com 93f9b95980Sapatard@mandriva.com /* wait for dco locked */ 94f9b95980Sapatard@mandriva.com do { 95f9b95980Sapatard@mandriva.com cpu_relax(); 96f9b95980Sapatard@mandriva.com value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); 972424d458SRussell King value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; 98f9b95980Sapatard@mandriva.com } while (value == 0); 99f9b95980Sapatard@mandriva.com } 100f9b95980Sapatard@mandriva.com 101363589bfSRussell King static void kirkwood_set_rate(struct snd_soc_dai *dai, 102363589bfSRussell King struct kirkwood_dma_data *priv, unsigned long rate) 103363589bfSRussell King { 104363589bfSRussell King uint32_t clks_ctrl; 105363589bfSRussell King 1061f1b6579SJean-Francois Moine if (IS_ERR(priv->extclk)) { 1078a537f85SJean-Francois Moine /* use internal dco for the supported rates 1088a537f85SJean-Francois Moine * defined in kirkwood_i2s_dai */ 109363589bfSRussell King dev_dbg(dai->dev, "%s: dco set rate = %lu\n", 110363589bfSRussell King __func__, rate); 111363589bfSRussell King kirkwood_set_dco(priv->io, rate); 112363589bfSRussell King 113363589bfSRussell King clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; 1148a537f85SJean-Francois Moine } else { 1158a537f85SJean-Francois Moine /* use the external clock for the other rates 1168a537f85SJean-Francois Moine * defined in kirkwood_i2s_dai_extclk */ 117363589bfSRussell King dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", 118363589bfSRussell King __func__, rate, 256 * rate); 119363589bfSRussell King clk_set_rate(priv->extclk, 256 * rate); 120363589bfSRussell King 121363589bfSRussell King clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK; 122363589bfSRussell King } 123363589bfSRussell King writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); 124363589bfSRussell King } 125363589bfSRussell King 126f0fba2adSLiam Girdwood static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, 127f0fba2adSLiam Girdwood struct snd_soc_dai *dai) 128f0fba2adSLiam Girdwood { 129f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 130f0fba2adSLiam Girdwood 131f0fba2adSLiam Girdwood snd_soc_dai_set_dma_data(dai, substream, priv); 132f0fba2adSLiam Girdwood return 0; 133f0fba2adSLiam Girdwood } 134f0fba2adSLiam Girdwood 135f9b95980Sapatard@mandriva.com static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, 136f9b95980Sapatard@mandriva.com struct snd_pcm_hw_params *params, 137f9b95980Sapatard@mandriva.com struct snd_soc_dai *dai) 138f9b95980Sapatard@mandriva.com { 139f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 140d8d11ba5SRussell King uint32_t ctl_play, ctl_rec; 141d8d11ba5SRussell King unsigned int i2s_reg; 142d8d11ba5SRussell King unsigned long i2s_value; 143f9b95980Sapatard@mandriva.com 144f9b95980Sapatard@mandriva.com if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 145f9b95980Sapatard@mandriva.com i2s_reg = KIRKWOOD_I2S_PLAYCTL; 146f9b95980Sapatard@mandriva.com } else { 147f9b95980Sapatard@mandriva.com i2s_reg = KIRKWOOD_I2S_RECCTL; 148f9b95980Sapatard@mandriva.com } 149f9b95980Sapatard@mandriva.com 150363589bfSRussell King kirkwood_set_rate(dai, priv, params_rate(params)); 151f9b95980Sapatard@mandriva.com 152f9b95980Sapatard@mandriva.com i2s_value = readl(priv->io+i2s_reg); 153f9b95980Sapatard@mandriva.com i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; 154f9b95980Sapatard@mandriva.com 155f9b95980Sapatard@mandriva.com /* 156f9b95980Sapatard@mandriva.com * Size settings in play/rec i2s control regs and play/rec control 157f9b95980Sapatard@mandriva.com * regs must be the same. 158f9b95980Sapatard@mandriva.com */ 159f9b95980Sapatard@mandriva.com switch (params_format(params)) { 160f9b95980Sapatard@mandriva.com case SNDRV_PCM_FORMAT_S16_LE: 161f9b95980Sapatard@mandriva.com i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; 162d8d11ba5SRussell King ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C | 163*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_I2S_EN | 164*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_SPDIF_EN; 165d8d11ba5SRussell King ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | 166*75b9b65eSJean-Francois Moine KIRKWOOD_RECCTL_I2S_EN | 167*75b9b65eSJean-Francois Moine KIRKWOOD_RECCTL_SPDIF_EN; 168f9b95980Sapatard@mandriva.com break; 169f9b95980Sapatard@mandriva.com /* 170f9b95980Sapatard@mandriva.com * doesn't work... S20_3LE != kirkwood 20bit format ? 171f9b95980Sapatard@mandriva.com * 172f9b95980Sapatard@mandriva.com case SNDRV_PCM_FORMAT_S20_3LE: 173f9b95980Sapatard@mandriva.com i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; 174d8d11ba5SRussell King ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | 175d8d11ba5SRussell King KIRKWOOD_PLAYCTL_I2S_EN; 176d8d11ba5SRussell King ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | 177d8d11ba5SRussell King KIRKWOOD_RECCTL_I2S_EN; 178f9b95980Sapatard@mandriva.com break; 179f9b95980Sapatard@mandriva.com */ 180f9b95980Sapatard@mandriva.com case SNDRV_PCM_FORMAT_S24_LE: 181f9b95980Sapatard@mandriva.com i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; 182d8d11ba5SRussell King ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | 183*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_I2S_EN | 184*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_SPDIF_EN; 185d8d11ba5SRussell King ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | 186*75b9b65eSJean-Francois Moine KIRKWOOD_RECCTL_I2S_EN | 187*75b9b65eSJean-Francois Moine KIRKWOOD_RECCTL_SPDIF_EN; 188f9b95980Sapatard@mandriva.com break; 189f9b95980Sapatard@mandriva.com case SNDRV_PCM_FORMAT_S32_LE: 190f9b95980Sapatard@mandriva.com i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; 191d8d11ba5SRussell King ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | 192d8d11ba5SRussell King KIRKWOOD_PLAYCTL_I2S_EN; 193d8d11ba5SRussell King ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | 194d8d11ba5SRussell King KIRKWOOD_RECCTL_I2S_EN; 195f9b95980Sapatard@mandriva.com break; 196f9b95980Sapatard@mandriva.com default: 197f9b95980Sapatard@mandriva.com return -EINVAL; 198f9b95980Sapatard@mandriva.com } 199dfe4c936Sarnaud.patard@rtp-net.org 200dfe4c936Sarnaud.patard@rtp-net.org if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 201dfe4c936Sarnaud.patard@rtp-net.org if (params_channels(params) == 1) 202d8d11ba5SRussell King ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH; 203dfe4c936Sarnaud.patard@rtp-net.org else 204d8d11ba5SRussell King ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; 205d8d11ba5SRussell King 206d8d11ba5SRussell King priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | 207db43b16fSRussell King KIRKWOOD_PLAYCTL_ENABLE_MASK | 208d8d11ba5SRussell King KIRKWOOD_PLAYCTL_SIZE_MASK); 209d8d11ba5SRussell King priv->ctl_play |= ctl_play; 210d8d11ba5SRussell King } else { 211d8d11ba5SRussell King priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK; 212d8d11ba5SRussell King priv->ctl_rec |= ctl_rec; 213dfe4c936Sarnaud.patard@rtp-net.org } 214dfe4c936Sarnaud.patard@rtp-net.org 215f9b95980Sapatard@mandriva.com writel(i2s_value, priv->io+i2s_reg); 216f9b95980Sapatard@mandriva.com 217f9b95980Sapatard@mandriva.com return 0; 218f9b95980Sapatard@mandriva.com } 219f9b95980Sapatard@mandriva.com 220f9b95980Sapatard@mandriva.com static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, 221f9b95980Sapatard@mandriva.com int cmd, struct snd_soc_dai *dai) 222f9b95980Sapatard@mandriva.com { 223f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 224982b604bSRussell King uint32_t ctl, value; 225f9b95980Sapatard@mandriva.com 226982b604bSRussell King ctl = readl(priv->io + KIRKWOOD_PLAYCTL); 227982b604bSRussell King if (ctl & KIRKWOOD_PLAYCTL_PAUSE) { 228982b604bSRussell King unsigned timeout = 5000; 229f9b95980Sapatard@mandriva.com /* 230982b604bSRussell King * The Armada510 spec says that if we enter pause mode, the 231982b604bSRussell King * busy bit must be read back as clear _twice_. Make sure 232982b604bSRussell King * we respect that otherwise we get DMA underruns. 233f9b95980Sapatard@mandriva.com */ 234982b604bSRussell King do { 235982b604bSRussell King value = ctl; 236982b604bSRussell King ctl = readl(priv->io + KIRKWOOD_PLAYCTL); 237982b604bSRussell King if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)) 238982b604bSRussell King break; 239982b604bSRussell King udelay(1); 240982b604bSRussell King } while (timeout--); 241982b604bSRussell King 242982b604bSRussell King if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) 243982b604bSRussell King dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", 244982b604bSRussell King ctl); 245982b604bSRussell King } 246f9b95980Sapatard@mandriva.com 247*75b9b65eSJean-Francois Moine if (dai->id == 0) 248*75b9b65eSJean-Francois Moine ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */ 249*75b9b65eSJean-Francois Moine else 250*75b9b65eSJean-Francois Moine ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN; /* spdif */ 251*75b9b65eSJean-Francois Moine 252f9b95980Sapatard@mandriva.com switch (cmd) { 253f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_START: 254d8d11ba5SRussell King /* configure */ 255d8d11ba5SRussell King ctl = priv->ctl_play; 256db43b16fSRussell King value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK; 257d8d11ba5SRussell King writel(value, priv->io + KIRKWOOD_PLAYCTL); 258d8d11ba5SRussell King 259d8d11ba5SRussell King /* enable interrupts */ 260f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_INT_MASK); 261f9b95980Sapatard@mandriva.com value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; 262f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_INT_MASK); 263f9b95980Sapatard@mandriva.com 264d8d11ba5SRussell King /* enable playback */ 265982b604bSRussell King writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 266f9b95980Sapatard@mandriva.com break; 267f9b95980Sapatard@mandriva.com 268f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_STOP: 269f9b95980Sapatard@mandriva.com /* stop audio, disable interrupts */ 270*75b9b65eSJean-Francois Moine ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 271*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_SPDIF_MUTE; 272982b604bSRussell King writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 273f9b95980Sapatard@mandriva.com 274f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_INT_MASK); 275f9b95980Sapatard@mandriva.com value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; 276f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_INT_MASK); 277f9b95980Sapatard@mandriva.com 278f9b95980Sapatard@mandriva.com /* disable all playbacks */ 279db43b16fSRussell King ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK; 280982b604bSRussell King writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 281f9b95980Sapatard@mandriva.com break; 282f9b95980Sapatard@mandriva.com 283f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 284f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_SUSPEND: 285*75b9b65eSJean-Francois Moine ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 286*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_SPDIF_MUTE; 287982b604bSRussell King writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 288f9b95980Sapatard@mandriva.com break; 289f9b95980Sapatard@mandriva.com 290f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_RESUME: 291f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 292*75b9b65eSJean-Francois Moine ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 293*75b9b65eSJean-Francois Moine KIRKWOOD_PLAYCTL_SPDIF_MUTE); 294982b604bSRussell King writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 295f9b95980Sapatard@mandriva.com break; 296f9b95980Sapatard@mandriva.com 297f9b95980Sapatard@mandriva.com default: 298f9b95980Sapatard@mandriva.com return -EINVAL; 299f9b95980Sapatard@mandriva.com } 300f9b95980Sapatard@mandriva.com 301f9b95980Sapatard@mandriva.com return 0; 302f9b95980Sapatard@mandriva.com } 303f9b95980Sapatard@mandriva.com 304f9b95980Sapatard@mandriva.com static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, 305f9b95980Sapatard@mandriva.com int cmd, struct snd_soc_dai *dai) 306f9b95980Sapatard@mandriva.com { 307f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 308d8d11ba5SRussell King uint32_t ctl, value; 309f9b95980Sapatard@mandriva.com 310f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 311f9b95980Sapatard@mandriva.com 312f9b95980Sapatard@mandriva.com switch (cmd) { 313f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_START: 314d8d11ba5SRussell King /* configure */ 315d8d11ba5SRussell King ctl = priv->ctl_rec; 316*75b9b65eSJean-Francois Moine if (dai->id == 0) 317*75b9b65eSJean-Francois Moine ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN; /* i2s */ 318*75b9b65eSJean-Francois Moine else 319*75b9b65eSJean-Francois Moine ctl &= ~KIRKWOOD_RECCTL_I2S_EN; /* spdif */ 320*75b9b65eSJean-Francois Moine 321*75b9b65eSJean-Francois Moine value = ctl & ~(KIRKWOOD_RECCTL_I2S_EN | 322*75b9b65eSJean-Francois Moine KIRKWOOD_RECCTL_SPDIF_EN); 323d8d11ba5SRussell King writel(value, priv->io + KIRKWOOD_RECCTL); 324d8d11ba5SRussell King 325d8d11ba5SRussell King /* enable interrupts */ 326f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_INT_MASK); 327f9b95980Sapatard@mandriva.com value |= KIRKWOOD_INT_CAUSE_REC_BYTES; 328f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_INT_MASK); 329f9b95980Sapatard@mandriva.com 330d8d11ba5SRussell King /* enable record */ 331d8d11ba5SRussell King writel(ctl, priv->io + KIRKWOOD_RECCTL); 332f9b95980Sapatard@mandriva.com break; 333f9b95980Sapatard@mandriva.com 334f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_STOP: 335f9b95980Sapatard@mandriva.com /* stop audio, disable interrupts */ 336f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 337b424ec95Sarnaud.patard@rtp-net.org value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE; 338f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_RECCTL); 339f9b95980Sapatard@mandriva.com 340f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_INT_MASK); 341f9b95980Sapatard@mandriva.com value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES; 342f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_INT_MASK); 343f9b95980Sapatard@mandriva.com 344f9b95980Sapatard@mandriva.com /* disable all records */ 345f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 346f9b95980Sapatard@mandriva.com value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN); 347f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_RECCTL); 348f9b95980Sapatard@mandriva.com break; 349f9b95980Sapatard@mandriva.com 350f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 351f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_SUSPEND: 352f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 353b424ec95Sarnaud.patard@rtp-net.org value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE; 354f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_RECCTL); 355f9b95980Sapatard@mandriva.com break; 356f9b95980Sapatard@mandriva.com 357f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_RESUME: 358f9b95980Sapatard@mandriva.com case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 359f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 360b424ec95Sarnaud.patard@rtp-net.org value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE); 361f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_RECCTL); 362f9b95980Sapatard@mandriva.com break; 363f9b95980Sapatard@mandriva.com 364f9b95980Sapatard@mandriva.com default: 365f9b95980Sapatard@mandriva.com return -EINVAL; 366f9b95980Sapatard@mandriva.com } 367f9b95980Sapatard@mandriva.com 368f9b95980Sapatard@mandriva.com return 0; 369f9b95980Sapatard@mandriva.com } 370f9b95980Sapatard@mandriva.com 371f9b95980Sapatard@mandriva.com static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 372f9b95980Sapatard@mandriva.com struct snd_soc_dai *dai) 373f9b95980Sapatard@mandriva.com { 374f9b95980Sapatard@mandriva.com if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 375f9b95980Sapatard@mandriva.com return kirkwood_i2s_play_trigger(substream, cmd, dai); 376f9b95980Sapatard@mandriva.com else 377f9b95980Sapatard@mandriva.com return kirkwood_i2s_rec_trigger(substream, cmd, dai); 378f9b95980Sapatard@mandriva.com 379f9b95980Sapatard@mandriva.com return 0; 380f9b95980Sapatard@mandriva.com } 381f9b95980Sapatard@mandriva.com 382*75b9b65eSJean-Francois Moine static int kirkwood_i2s_init(struct kirkwood_dma_data *priv) 383f9b95980Sapatard@mandriva.com { 384f9b95980Sapatard@mandriva.com unsigned long value; 385f9b95980Sapatard@mandriva.com unsigned int reg_data; 386f9b95980Sapatard@mandriva.com 387f9b95980Sapatard@mandriva.com /* put system in a "safe" state : */ 388f9b95980Sapatard@mandriva.com /* disable audio interrupts */ 389f9b95980Sapatard@mandriva.com writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE); 390f9b95980Sapatard@mandriva.com writel(0, priv->io + KIRKWOOD_INT_MASK); 391f9b95980Sapatard@mandriva.com 392f9b95980Sapatard@mandriva.com reg_data = readl(priv->io + 0x1200); 393f9b95980Sapatard@mandriva.com reg_data &= (~(0x333FF8)); 394f9b95980Sapatard@mandriva.com reg_data |= 0x111D18; 395f9b95980Sapatard@mandriva.com writel(reg_data, priv->io + 0x1200); 396f9b95980Sapatard@mandriva.com 397f9b95980Sapatard@mandriva.com msleep(500); 398f9b95980Sapatard@mandriva.com 399f9b95980Sapatard@mandriva.com reg_data = readl(priv->io + 0x1200); 400f9b95980Sapatard@mandriva.com reg_data &= (~(0x333FF8)); 401f9b95980Sapatard@mandriva.com reg_data |= 0x111D18; 402f9b95980Sapatard@mandriva.com writel(reg_data, priv->io + 0x1200); 403f9b95980Sapatard@mandriva.com 404f9b95980Sapatard@mandriva.com /* disable playback/record */ 405f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_PLAYCTL); 406db43b16fSRussell King value &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK; 407f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_PLAYCTL); 408f9b95980Sapatard@mandriva.com 409f9b95980Sapatard@mandriva.com value = readl(priv->io + KIRKWOOD_RECCTL); 410f9b95980Sapatard@mandriva.com value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN); 411f9b95980Sapatard@mandriva.com writel(value, priv->io + KIRKWOOD_RECCTL); 412f9b95980Sapatard@mandriva.com 413f9b95980Sapatard@mandriva.com return 0; 414f9b95980Sapatard@mandriva.com 415f9b95980Sapatard@mandriva.com } 416f9b95980Sapatard@mandriva.com 41785e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { 418f0fba2adSLiam Girdwood .startup = kirkwood_i2s_startup, 419f9b95980Sapatard@mandriva.com .trigger = kirkwood_i2s_trigger, 420f9b95980Sapatard@mandriva.com .hw_params = kirkwood_i2s_hw_params, 421f9b95980Sapatard@mandriva.com .set_fmt = kirkwood_i2s_set_fmt, 422f9b95980Sapatard@mandriva.com }; 423f9b95980Sapatard@mandriva.com 424*75b9b65eSJean-Francois Moine static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = { 425*75b9b65eSJean-Francois Moine { 426*75b9b65eSJean-Francois Moine .name = "i2s", 427*75b9b65eSJean-Francois Moine .id = 0, 428f9b95980Sapatard@mandriva.com .playback = { 429f9b95980Sapatard@mandriva.com .channels_min = 1, 430f9b95980Sapatard@mandriva.com .channels_max = 2, 4319e12cbd9SMark Brown .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 4329e12cbd9SMark Brown SNDRV_PCM_RATE_96000, 433363589bfSRussell King .formats = KIRKWOOD_I2S_FORMATS, 434363589bfSRussell King }, 435f9b95980Sapatard@mandriva.com .capture = { 436f9b95980Sapatard@mandriva.com .channels_min = 1, 437f9b95980Sapatard@mandriva.com .channels_max = 2, 4389e12cbd9SMark Brown .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 4399e12cbd9SMark Brown SNDRV_PCM_RATE_96000, 440363589bfSRussell King .formats = KIRKWOOD_I2S_FORMATS, 441363589bfSRussell King }, 442363589bfSRussell King .ops = &kirkwood_i2s_dai_ops, 443*75b9b65eSJean-Francois Moine }, 444*75b9b65eSJean-Francois Moine { 445*75b9b65eSJean-Francois Moine .name = "spdif", 446*75b9b65eSJean-Francois Moine .id = 1, 447*75b9b65eSJean-Francois Moine .playback = { 448*75b9b65eSJean-Francois Moine .channels_min = 1, 449*75b9b65eSJean-Francois Moine .channels_max = 2, 450*75b9b65eSJean-Francois Moine .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 451*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_96000, 452*75b9b65eSJean-Francois Moine .formats = KIRKWOOD_I2S_FORMATS, 453*75b9b65eSJean-Francois Moine }, 454*75b9b65eSJean-Francois Moine .capture = { 455*75b9b65eSJean-Francois Moine .channels_min = 1, 456*75b9b65eSJean-Francois Moine .channels_max = 2, 457*75b9b65eSJean-Francois Moine .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 458*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_96000, 459*75b9b65eSJean-Francois Moine .formats = KIRKWOOD_I2S_FORMATS, 460*75b9b65eSJean-Francois Moine }, 461*75b9b65eSJean-Francois Moine .ops = &kirkwood_i2s_dai_ops, 462*75b9b65eSJean-Francois Moine }, 463363589bfSRussell King }; 464363589bfSRussell King 465*75b9b65eSJean-Francois Moine static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = { 466*75b9b65eSJean-Francois Moine { 467*75b9b65eSJean-Francois Moine .name = "i2s", 468*75b9b65eSJean-Francois Moine .id = 0, 469363589bfSRussell King .playback = { 470363589bfSRussell King .channels_min = 1, 471363589bfSRussell King .channels_max = 2, 472363589bfSRussell King .rates = SNDRV_PCM_RATE_8000_192000 | 473363589bfSRussell King SNDRV_PCM_RATE_CONTINUOUS | 474363589bfSRussell King SNDRV_PCM_RATE_KNOT, 475363589bfSRussell King .formats = KIRKWOOD_I2S_FORMATS, 476363589bfSRussell King }, 477363589bfSRussell King .capture = { 478363589bfSRussell King .channels_min = 1, 479363589bfSRussell King .channels_max = 2, 480363589bfSRussell King .rates = SNDRV_PCM_RATE_8000_192000 | 481363589bfSRussell King SNDRV_PCM_RATE_CONTINUOUS | 482363589bfSRussell King SNDRV_PCM_RATE_KNOT, 483363589bfSRussell King .formats = KIRKWOOD_I2S_FORMATS, 484363589bfSRussell King }, 485f9b95980Sapatard@mandriva.com .ops = &kirkwood_i2s_dai_ops, 486*75b9b65eSJean-Francois Moine }, 487*75b9b65eSJean-Francois Moine { 488*75b9b65eSJean-Francois Moine .name = "spdif", 489*75b9b65eSJean-Francois Moine .id = 1, 490*75b9b65eSJean-Francois Moine .playback = { 491*75b9b65eSJean-Francois Moine .channels_min = 1, 492*75b9b65eSJean-Francois Moine .channels_max = 2, 493*75b9b65eSJean-Francois Moine .rates = SNDRV_PCM_RATE_8000_192000 | 494*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_CONTINUOUS | 495*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_KNOT, 496*75b9b65eSJean-Francois Moine .formats = KIRKWOOD_I2S_FORMATS, 497*75b9b65eSJean-Francois Moine }, 498*75b9b65eSJean-Francois Moine .capture = { 499*75b9b65eSJean-Francois Moine .channels_min = 1, 500*75b9b65eSJean-Francois Moine .channels_max = 2, 501*75b9b65eSJean-Francois Moine .rates = SNDRV_PCM_RATE_8000_192000 | 502*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_CONTINUOUS | 503*75b9b65eSJean-Francois Moine SNDRV_PCM_RATE_KNOT, 504*75b9b65eSJean-Francois Moine .formats = KIRKWOOD_I2S_FORMATS, 505*75b9b65eSJean-Francois Moine }, 506*75b9b65eSJean-Francois Moine .ops = &kirkwood_i2s_dai_ops, 507*75b9b65eSJean-Francois Moine }, 508f9b95980Sapatard@mandriva.com }; 509f9b95980Sapatard@mandriva.com 51083d85f53SKuninori Morimoto static const struct snd_soc_component_driver kirkwood_i2s_component = { 51183d85f53SKuninori Morimoto .name = DRV_NAME, 51283d85f53SKuninori Morimoto }; 51383d85f53SKuninori Morimoto 51434e15fbdSBill Pemberton static int kirkwood_i2s_dev_probe(struct platform_device *pdev) 515f9b95980Sapatard@mandriva.com { 516363589bfSRussell King struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; 517*75b9b65eSJean-Francois Moine struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; 518f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv; 519363589bfSRussell King struct resource *mem; 520eb632318SJean-Francois Moine struct device_node *np = pdev->dev.of_node; 521f9b95980Sapatard@mandriva.com int err; 522f9b95980Sapatard@mandriva.com 523dbc517bfSRussell King priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 524f9b95980Sapatard@mandriva.com if (!priv) { 525f9b95980Sapatard@mandriva.com dev_err(&pdev->dev, "allocation failed\n"); 526dbc517bfSRussell King return -ENOMEM; 527f9b95980Sapatard@mandriva.com } 528f0fba2adSLiam Girdwood dev_set_drvdata(&pdev->dev, priv); 529f9b95980Sapatard@mandriva.com 530f9b95980Sapatard@mandriva.com mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 531b25b5aa0SThierry Reding priv->io = devm_ioremap_resource(&pdev->dev, mem); 532b25b5aa0SThierry Reding if (IS_ERR(priv->io)) 533b25b5aa0SThierry Reding return PTR_ERR(priv->io); 534f9b95980Sapatard@mandriva.com 535f9b95980Sapatard@mandriva.com priv->irq = platform_get_irq(pdev, 0); 536f9b95980Sapatard@mandriva.com if (priv->irq <= 0) { 537f9b95980Sapatard@mandriva.com dev_err(&pdev->dev, "platform_get_irq failed\n"); 538dbc517bfSRussell King return -ENXIO; 539f9b95980Sapatard@mandriva.com } 540f9b95980Sapatard@mandriva.com 541eb632318SJean-Francois Moine if (np) { 542eb632318SJean-Francois Moine priv->burst = 128; /* might be 32 or 128 */ 543eb632318SJean-Francois Moine } else if (data) { 544eb632318SJean-Francois Moine priv->burst = data->burst; 545eb632318SJean-Francois Moine } else { 546eb632318SJean-Francois Moine dev_err(&pdev->dev, "no DT nor platform data ?!\n"); 547dbc517bfSRussell King return -EINVAL; 548f9b95980Sapatard@mandriva.com } 549f9b95980Sapatard@mandriva.com 550eb632318SJean-Francois Moine priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL); 551e919c716SAndrew Lunn if (IS_ERR(priv->clk)) { 552e919c716SAndrew Lunn dev_err(&pdev->dev, "no clock\n"); 553dbc517bfSRussell King return PTR_ERR(priv->clk); 554e919c716SAndrew Lunn } 555dbc517bfSRussell King 556dbc517bfSRussell King err = clk_prepare_enable(priv->clk); 557dbc517bfSRussell King if (err < 0) 558dbc517bfSRussell King return err; 559e919c716SAndrew Lunn 5604734dc96SMark Brown priv->extclk = devm_clk_get(&pdev->dev, "extclk"); 56184aac6c7SJean-Francois Moine if (IS_ERR(priv->extclk)) { 56284aac6c7SJean-Francois Moine if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) 56384aac6c7SJean-Francois Moine return -EPROBE_DEFER; 56484aac6c7SJean-Francois Moine } else { 565d8d11ba5SRussell King if (priv->extclk == priv->clk) { 566af64d734SRussell King devm_clk_put(&pdev->dev, priv->extclk); 567d8d11ba5SRussell King priv->extclk = ERR_PTR(-EINVAL); 568d8d11ba5SRussell King } else { 569d8d11ba5SRussell King dev_info(&pdev->dev, "found external clock\n"); 570d8d11ba5SRussell King clk_prepare_enable(priv->extclk); 571d8d11ba5SRussell King soc_dai = &kirkwood_i2s_dai_extclk; 572d8d11ba5SRussell King } 573d8d11ba5SRussell King } 574d8d11ba5SRussell King 575d8d11ba5SRussell King /* Some sensible defaults - this reflects the powerup values */ 576d8d11ba5SRussell King priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; 577d8d11ba5SRussell King priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; 578d8d11ba5SRussell King 579d8d11ba5SRussell King /* Select the burst size */ 580eb632318SJean-Francois Moine if (priv->burst == 32) { 581d8d11ba5SRussell King priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 582d8d11ba5SRussell King priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 583d8d11ba5SRussell King } else { 584d8d11ba5SRussell King priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; 585d8d11ba5SRussell King priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; 586d8d11ba5SRussell King } 587d8d11ba5SRussell King 58883d85f53SKuninori Morimoto err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, 589*75b9b65eSJean-Francois Moine soc_dai, 2); 59064ddf1f8SRussell King if (err) { 59183d85f53SKuninori Morimoto dev_err(&pdev->dev, "snd_soc_register_component failed\n"); 59264ddf1f8SRussell King goto err_component; 59364ddf1f8SRussell King } 594baffab28SSimon Baatz 59564ddf1f8SRussell King err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform); 59664ddf1f8SRussell King if (err) { 59764ddf1f8SRussell King dev_err(&pdev->dev, "snd_soc_register_platform failed\n"); 59864ddf1f8SRussell King goto err_platform; 59964ddf1f8SRussell King } 600*75b9b65eSJean-Francois Moine 601*75b9b65eSJean-Francois Moine kirkwood_i2s_init(priv); 602*75b9b65eSJean-Francois Moine 60364ddf1f8SRussell King return 0; 60464ddf1f8SRussell King err_platform: 60564ddf1f8SRussell King snd_soc_unregister_component(&pdev->dev); 60664ddf1f8SRussell King err_component: 6074734dc96SMark Brown if (!IS_ERR(priv->extclk)) 608363589bfSRussell King clk_disable_unprepare(priv->extclk); 609baffab28SSimon Baatz clk_disable_unprepare(priv->clk); 610f9b95980Sapatard@mandriva.com 611f9b95980Sapatard@mandriva.com return err; 612f9b95980Sapatard@mandriva.com } 613f9b95980Sapatard@mandriva.com 61434e15fbdSBill Pemberton static int kirkwood_i2s_dev_remove(struct platform_device *pdev) 615f9b95980Sapatard@mandriva.com { 616f0fba2adSLiam Girdwood struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 617f0fba2adSLiam Girdwood 61864ddf1f8SRussell King snd_soc_unregister_platform(&pdev->dev); 61983d85f53SKuninori Morimoto snd_soc_unregister_component(&pdev->dev); 620e919c716SAndrew Lunn 6214734dc96SMark Brown if (!IS_ERR(priv->extclk)) 622363589bfSRussell King clk_disable_unprepare(priv->extclk); 623e919c716SAndrew Lunn clk_disable_unprepare(priv->clk); 624f0fba2adSLiam Girdwood 625f9b95980Sapatard@mandriva.com return 0; 626f9b95980Sapatard@mandriva.com } 627f9b95980Sapatard@mandriva.com 628eb632318SJean-Francois Moine #ifdef CONFIG_OF 629eb632318SJean-Francois Moine static struct of_device_id mvebu_audio_of_match[] = { 630d098b2f0SThomas Petazzoni { .compatible = "marvell,kirkwood-audio" }, 631d098b2f0SThomas Petazzoni { .compatible = "marvell,dove-audio" }, 632eb632318SJean-Francois Moine { } 633eb632318SJean-Francois Moine }; 634eb632318SJean-Francois Moine MODULE_DEVICE_TABLE(of, mvebu_audio_of_match); 635eb632318SJean-Francois Moine #endif 636eb632318SJean-Francois Moine 637f9b95980Sapatard@mandriva.com static struct platform_driver kirkwood_i2s_driver = { 638f9b95980Sapatard@mandriva.com .probe = kirkwood_i2s_dev_probe, 63934e15fbdSBill Pemberton .remove = kirkwood_i2s_dev_remove, 640f9b95980Sapatard@mandriva.com .driver = { 641f9b95980Sapatard@mandriva.com .name = DRV_NAME, 642f9b95980Sapatard@mandriva.com .owner = THIS_MODULE, 643eb632318SJean-Francois Moine .of_match_table = of_match_ptr(mvebu_audio_of_match), 644f9b95980Sapatard@mandriva.com }, 645f9b95980Sapatard@mandriva.com }; 646f9b95980Sapatard@mandriva.com 64741b10225SAxel Lin module_platform_driver(kirkwood_i2s_driver); 648f9b95980Sapatard@mandriva.com 649f9b95980Sapatard@mandriva.com /* Module information */ 65069737897SArnaud Patard (Rtp) MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>"); 651f9b95980Sapatard@mandriva.com MODULE_DESCRIPTION("Kirkwood I2S SoC Interface"); 652f9b95980Sapatard@mandriva.com MODULE_LICENSE("GPL"); 65364ddf1f8SRussell King MODULE_ALIAS("platform:mvebu-audio"); 654